Added serverGame library

This commit is contained in:
Anonymous
2014-01-15 03:59:18 -07:00
parent 89291fb38c
commit 0196cf51d0
1032 changed files with 256379 additions and 0 deletions
@@ -0,0 +1,174 @@
// ======================================================================
//
// AiServerShipObjectInterface.cpp
//
// copyright 2004, sony online entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/AiServerShipObjectInterface.h"
#include "serverGame/AiShipPilotData.h"
#include "serverGame/ShipObject.h"
#include "sharedFoundation/ConfigFile.h"
// ======================================================================
//
// AiServerShipObjectInterfaceNamespace
//
// ======================================================================
namespace AiServerShipObjectInterfaceNamespace
{
bool s_fastAxis = true;
}
using namespace AiServerShipObjectInterfaceNamespace;
// ======================================================================
//
// AiServerShipObjectInterface
//
// ======================================================================
// ----------------------------------------------------------------------
void AiServerShipObjectInterface::install()
{
setFastAxisEnabled(ConfigFile::getKeyBool("GameServer", "spaceAiFastAxisEnabled", true));
}
// ----------------------------------------------------------------------
AiServerShipObjectInterface::AiServerShipObjectInterface(ShipObject const * const shipObject, AiShipPilotData const & aiShipPilotData, bool const modifySpeed)
: ServerShipObjectInterface(shipObject)
, m_modifySpeed(modifySpeed)
, m_aiShipPilotData(aiShipPilotData)
{
}
// ----------------------------------------------------------------------
float AiServerShipObjectInterface::getMaximumSpeed() const
{
float const maximumSpeed = ServerShipObjectInterface::getMaximumSpeed();
if (!m_modifySpeed)
{
return (maximumSpeed * m_aiShipPilotData.m_nonCombatMaxSpeedPercent);
}
return maximumSpeed;
}
// ----------------------------------------------------------------------
float AiServerShipObjectInterface::getSpeedAcceleration() const
{
float const speedAcceleration = ServerShipObjectInterface::getSpeedAcceleration();
if (!m_modifySpeed)
{
float const maximumSpeed = getMaximumSpeed();
return std::max(speedAcceleration, maximumSpeed * 2.0f);
}
return speedAcceleration;
}
// ----------------------------------------------------------------------
float AiServerShipObjectInterface::getSpeedDeceleration() const
{
float const speedDeceleration = ServerShipObjectInterface::getSpeedDeceleration();
if (!m_modifySpeed)
{
float const maximumSpeed = getMaximumSpeed();
return std::max(speedDeceleration, maximumSpeed * 2.0f);
}
return speedDeceleration;
}
// ----------------------------------------------------------------------
float AiServerShipObjectInterface::getSlideDampener() const
{
float const slideDampener = ServerShipObjectInterface::getSlideDampener();
return slideDampener;
}
// ----------------------------------------------------------------------
float AiServerShipObjectInterface::getMaximumYaw() const
{
float const maximumYaw = ServerShipObjectInterface::getMaximumYaw();
return maximumYaw;
}
// ----------------------------------------------------------------------
float AiServerShipObjectInterface::getYawAcceleration() const
{
float const yawAcceleration = ServerShipObjectInterface::getYawAcceleration();
return yawAcceleration;
}
// ----------------------------------------------------------------------
float AiServerShipObjectInterface::getMaximumPitch() const
{
float const maximumPitch = ServerShipObjectInterface::getMaximumPitch();
return maximumPitch;
}
// ----------------------------------------------------------------------
float AiServerShipObjectInterface::getPitchAcceleration() const
{
float const pitchAcceleration = ServerShipObjectInterface::getPitchAcceleration();
return pitchAcceleration;
}
// ----------------------------------------------------------------------
float AiServerShipObjectInterface::getMaximumRoll() const
{
float const maximumRoll = ServerShipObjectInterface::getMaximumRoll();
return maximumRoll;
}
// ----------------------------------------------------------------------
float AiServerShipObjectInterface::getRollAcceleration() const
{
float const rollAcceleration = ServerShipObjectInterface::getRollAcceleration();
return rollAcceleration;
}
// ----------------------------------------------------------------------
void AiServerShipObjectInterface::setFastAxisEnabled(bool const enabled)
{
s_fastAxis = enabled;
}
// ----------------------------------------------------------------------
bool AiServerShipObjectInterface::isFastAxisEnabled()
{
return s_fastAxis;
}
// ======================================================================
@@ -0,0 +1,56 @@
// ======================================================================
//
// AiServerShipObjectInterface.h
//
// copyright 2004, sony online entertainment
//
// ======================================================================
#ifndef INCLUDED_AiServerShipObjectInterface_H
#define INCLUDED_AiServerShipObjectInterface_H
// ======================================================================
#include "serverGame/ServerShipObjectInterface.h"
struct AiShipPilotData;
class ShipObject;
// ======================================================================
class AiServerShipObjectInterface : public ServerShipObjectInterface
{
public:
static void install();
static void setFastAxisEnabled(bool const enabled);
static bool isFastAxisEnabled();
public:
AiServerShipObjectInterface(ShipObject const * shipObject, AiShipPilotData const & aiShipPilotData, bool const modifySpeed);
virtual float getMaximumSpeed() const;
virtual float getSpeedAcceleration() const;
virtual float getSpeedDeceleration() const;
virtual float getSlideDampener() const;
virtual float getMaximumYaw() const;
virtual float getYawAcceleration() const;
virtual float getMaximumPitch() const;
virtual float getPitchAcceleration() const;
virtual float getMaximumRoll() const;
virtual float getRollAcceleration() const;
private:
bool const m_modifySpeed;
AiShipPilotData const & m_aiShipPilotData;
AiServerShipObjectInterface();
AiServerShipObjectInterface(AiServerShipObjectInterface const &);
AiServerShipObjectInterface & operator=(AiServerShipObjectInterface const &);
};
// ======================================================================
#endif // INCLUDED_AiServerShipObjectInterface_H
@@ -0,0 +1,37 @@
// ======================================================================
//
// BaselineDistributionListPool.cpp
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/BaselineDistributionListPool.h"
#include "serverGame/Client.h"
// ======================================================================
static std::map<ServerObject const *, std::vector<Watcher<Client> > > s_pools;
// ======================================================================
std::vector<Watcher<Client> > *BaselineDistributionListPool::get(ServerObject const &obj, bool allocIfNeeded) // static
{
if (allocIfNeeded)
return &(s_pools[&obj]);
std::map<ServerObject const *, std::vector<Watcher<Client> > >::iterator i = s_pools.find(&obj);
if (i != s_pools.end())
return &((*i).second);
return 0;
}
// ----------------------------------------------------------------------
void BaselineDistributionListPool::free(ServerObject const &obj) // static
{
s_pools.erase(&obj);
}
// ======================================================================
@@ -0,0 +1,30 @@
// ======================================================================
//
// BaselineDistributionListPool.h
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#ifndef _BaselineDistributionListPool_H_
#define _BaselineDistributionListPool_H_
// ======================================================================
template <typename T> class Watcher;
class ServerObject;
class Client;
// ======================================================================
class BaselineDistributionListPool
{
public:
static stdvector<Watcher<Client> >::fwd *get(ServerObject const &obj, bool allocIfNeeded);
static void free(ServerObject const &obj);
};
// ======================================================================
#endif // _BaselineDistributionListPool_H_
@@ -0,0 +1,197 @@
// ======================================================================
//
// BattlefieldMarkerObject.h
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/BattlefieldMarkerObject.h"
#include "serverGame/BattlefieldMarkerController.h"
#include "serverGame/Pvp.h"
#include "serverGame/RegionMaster.h"
#include "serverGame/ServerBattlefieldMarkerObjectTemplate.h"
#include "sharedNetworkMessages/MessageQueueGenericValueType.h"
#include "sharedObject/NetworkIdManager.h"
// ======================================================================
static std::map<std::string, BattlefieldMarkerObject *> s_markerMap;
// ======================================================================
static void removeFromMarkerMap(std::string const &regionName, BattlefieldMarkerObject *marker)
{
if (regionName.length())
{
std::map<std::string, BattlefieldMarkerObject*>::iterator i = s_markerMap.find(regionName);
if (i != s_markerMap.end() && (*i).second == marker)
{
s_markerMap.erase(i);
RegionMaster::registerBattlefieldMarker(regionName, 0);
}
}
}
// ----------------------------------------------------------------------
static bool addToMarkerMap(std::string const &regionName, BattlefieldMarkerObject *marker)
{
if (regionName.length())
{
std::map<std::string, BattlefieldMarkerObject*>::iterator i = s_markerMap.find(regionName);
if (i != s_markerMap.end())
return false;
s_markerMap[regionName] = marker;
RegionMaster::registerBattlefieldMarker(regionName, marker);
}
return true;
}
// ======================================================================
BattlefieldMarkerObject::BattlefieldMarkerObject(ServerBattlefieldMarkerObjectTemplate const *newTemplate) :
TangibleObject(newTemplate),
m_regionName(),
m_battlefieldParticipants()
{
addMembersToPackages();
m_regionName.setSourceObject(this);
m_battlefieldParticipants.setOnSet(this, &BattlefieldMarkerObject::onParticipantSet);
m_battlefieldParticipants.setOnInsert(this, &BattlefieldMarkerObject::onParticipantInsert);
m_battlefieldParticipants.setOnErase(this, &BattlefieldMarkerObject::onParticipantErase);
}
// ----------------------------------------------------------------------
BattlefieldMarkerObject::~BattlefieldMarkerObject()
{
removeFromMarkerMap(m_regionName.get(), this);
}
// ----------------------------------------------------------------------
void BattlefieldMarkerObject::onLoadedFromDatabase()
{
setPlacing(true);
TangibleObject::onLoadedFromDatabase();
}
// ----------------------------------------------------------------------
void BattlefieldMarkerObject::onRegionNameChanged(std::string const &oldName, std::string const &newName)
{
removeFromMarkerMap(oldName, this);
if (!addToMarkerMap(newName, this))
{
WARNING(true, ("Tried to create a duplicate battlefield marker %s, destroying it.", newName.c_str()));
permanentlyDestroy(DeleteReasons::SetupFailed);
}
}
// ----------------------------------------------------------------------
Controller *BattlefieldMarkerObject::createDefaultController()
{
Controller * _controller = new BattlefieldMarkerController(this);
NOT_NULL(_controller);
setController(_controller);
return _controller;
}
// ----------------------------------------------------------------------
void BattlefieldMarkerObject::setRegionName(std::string const &newName)
{
m_regionName.set(newName);
}
// ----------------------------------------------------------------------
std::string const &BattlefieldMarkerObject::getRegionName() const
{
return m_regionName.get();
}
// ----------------------------------------------------------------------
std::map<NetworkId, uint32> const &BattlefieldMarkerObject::getBattlefieldParticipants() const
{
return m_battlefieldParticipants.getMap();
}
// ----------------------------------------------------------------------
uint32 BattlefieldMarkerObject::getBattlefieldFactionId(NetworkId const &who) const
{
std::map<NetworkId, uint32>::const_iterator i = m_battlefieldParticipants.find(who);
if (i != m_battlefieldParticipants.end())
return (*i).second;
return 0;
}
// ----------------------------------------------------------------------
void BattlefieldMarkerObject::setBattlefieldParticipant(NetworkId const &who, uint32 factionId)
{
if (!isAuthoritative())
sendControllerMessageToAuthServer(CM_setBattlefieldParticipant, new MessageQueueGenericValueType<std::pair<NetworkId, uint32> >(std::make_pair(who, factionId)));
else if (factionId)
m_battlefieldParticipants.set(who, factionId);
else
m_battlefieldParticipants.erase(who);
}
// ----------------------------------------------------------------------
void BattlefieldMarkerObject::clearBattlefieldParticipants()
{
if (!isAuthoritative())
sendControllerMessageToAuthServer(CM_clearBattlefieldParticipants, 0);
else
m_battlefieldParticipants.clear();
}
// ----------------------------------------------------------------------
void BattlefieldMarkerObject::onParticipantSet(NetworkId const &who, uint32 const &, uint32 const &)
{
TangibleObject *tangible = dynamic_cast<TangibleObject *>(NetworkIdManager::getObjectById(who));
if (tangible)
Pvp::forceStatusUpdate(*tangible);
}
// ----------------------------------------------------------------------
void BattlefieldMarkerObject::onParticipantInsert(NetworkId const &who, uint32 const &)
{
TangibleObject *tangible = dynamic_cast<TangibleObject *>(NetworkIdManager::getObjectById(who));
if (tangible)
Pvp::forceStatusUpdate(*tangible);
}
// ----------------------------------------------------------------------
void BattlefieldMarkerObject::onParticipantErase(NetworkId const &who, uint32 const &)
{
TangibleObject *tangible = dynamic_cast<TangibleObject *>(NetworkIdManager::getObjectById(who));
if (tangible)
Pvp::forceStatusUpdate(*tangible);
}
// ----------------------------------------------------------------------
BattlefieldMarkerObject *BattlefieldMarkerObject::findMarkerByRegionName(std::string const &regionName) // static
{
std::map<std::string, BattlefieldMarkerObject *>::iterator i = s_markerMap.find(regionName);
if (i != s_markerMap.end())
return (*i).second;
return 0;
}
// ======================================================================
@@ -0,0 +1,78 @@
// ======================================================================
//
// BattlefieldMarkerObject.h
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#ifndef _INCLUDED_BattlefieldMarkerObject_H
#define _INCLUDED_BattlefieldMarkerObject_H
// ======================================================================
#include "serverGame/TangibleObject.h"
#include "Archive/AutoDeltaMap.h"
// ======================================================================
class ServerBattlefieldMarkerObjectTemplate;
// ======================================================================
class BattlefieldMarkerObject: public TangibleObject
{
friend class BattlefieldMarkerController;
public:
BattlefieldMarkerObject(ServerBattlefieldMarkerObjectTemplate const *newTemplate);
virtual ~BattlefieldMarkerObject();
static BattlefieldMarkerObject *findMarkerByRegionName(std::string const &regionName);
virtual Controller *createDefaultController();
void setRegionName(std::string const &newName);
std::string const &getRegionName() const;
uint32 getBattlefieldFactionId(NetworkId const &who) const;
void setBattlefieldParticipant(NetworkId const &who, uint32 factionId);
void clearBattlefieldParticipants();
std::map<NetworkId, uint32> const &getBattlefieldParticipants() const;
void onParticipantSet(NetworkId const &who, uint32 const &, uint32 const &);
void onParticipantInsert(NetworkId const &who, uint32 const &);
void onParticipantErase(NetworkId const &who, uint32 const &);
void onRegionNameChanged(std::string const &oldName, std::string const &newName);
protected:
virtual void onLoadedFromDatabase();
private:
BattlefieldMarkerObject();
BattlefieldMarkerObject(BattlefieldMarkerObject const &);
BattlefieldMarkerObject &operator=(BattlefieldMarkerObject const &);
void addMembersToPackages();
private:
struct RegionNameCallback
{
void modified(BattlefieldMarkerObject &target, std::string const &oldValue, std::string const &newValue, bool) const;
};
//BPM BattlefieldMarkerObject : TangibleObject // Begin persisted members.
Archive::AutoDeltaVariableCallback<std::string, RegionNameCallback, BattlefieldMarkerObject> m_regionName;
Archive::AutoDeltaMap<NetworkId, uint32, BattlefieldMarkerObject> m_battlefieldParticipants;
//EPM
};
// ======================================================================
inline void BattlefieldMarkerObject::RegionNameCallback::modified(BattlefieldMarkerObject &target, std::string const &oldValue, std::string const &newValue, bool) const
{
target.onRegionNameChanged(oldValue, newValue);
}
// ======================================================================
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,194 @@
// ======================================================================
//
// BuildingObject.h
//
// Copyright 2002 Sony Online Entertainment
//
// ======================================================================
#ifndef BuildingObject_H
#define BuildingObject_H
// ======================================================================
#include "Archive/AutoDeltaSetObserver.h"
#include "serverGame/TangibleObject.h"
#include "serverGame/CellPermissions.h"
#include "sharedTerrain/TerrainGenerator.h"
// ======================================================================
class ServerBuildingObjectTemplate;
class CreatureObject;
// ======================================================================
/**
* A BuildingObject is the base class for all large structures that players will be placing.
*/
class BuildingObject : public TangibleObject
{
public:
explicit BuildingObject(const ServerBuildingObjectTemplate* newTemplate);
virtual ~BuildingObject();
virtual BuildingObject * asBuildingObject();
virtual BuildingObject const * asBuildingObject() const;
virtual float alter(float time);
static void removeDefaultTemplate(void);
virtual Controller* createDefaultController(void);
void addMembersToPackages ();
virtual void getAttributes (stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const;
int getMaintenanceCost() const;
void setMaintenanceCost(int newConst);
real getTimeLastChecked() const;
void setTimeLastChecked(real newTime);
int getCityId() const;
void setCityId(int cityId);
bool getIsPublic() const;
void setIsPublic(bool isPublic);
void addBanned(std::string const &name);
void removeBanned(std::string const &name);
void removeAllBanned();
void addAllowed(std::string const &name);
void removeAllowed(std::string const &name);
void removeAllAllowed();
bool isAllowed(CreatureObject const &who) const;
bool isPlayerPlaced() const;
bool isSpaceDungeon() const;
bool playersWithAlignedEnemyFlagsAllowed() const;
virtual bool isVisibleOnClient(const Client & client) const;
CellPermissions::PermissionList const &getAllowed() const;
CellPermissions::PermissionList const &getBanned() const;
void expelObject(ServerObject &who);
bool getContentsLoaded() const;
void handleCMessageTo(const MessageToPayload &message);
virtual void onPermanentlyDestroyed();
virtual void onAllContentsLoaded();
void onCellContentsLoaded();
virtual void onAddedToWorld();
void gainedPlayer(ServerObject const &player);
void lostPlayer(ServerObject const &player);
virtual void changeTeleportDestination(Vector & position, float & yaw) const;
void loadContents(bool immediate = false);
bool unloadContents();
struct BuildingObjectPointerHash
{
size_t operator()(const BuildingObject * const ptr) const
{
return (reinterpret_cast<const size_t>(ptr) >> 4);
};
};
typedef stdhash_set<const BuildingObject *, BuildingObjectPointerHash>::fwd AllBuildingsSet;
static const AllBuildingsSet & getAllBuildings();
protected:
virtual void initializeFirstTimeObject();
virtual void endBaselines();
virtual void onLoadedFromDatabase();
virtual const SharedObjectTemplate * getDefaultSharedTemplate(void) const;
private:
BuildingObject();
BuildingObject(const BuildingObject& rhs);
BuildingObject& operator=(const BuildingObject& rhs);
typedef Archive::AutoDeltaVariableObserver<bool, CellPermissions::UpdateObserver, BuildingObject> ObservedBool;
typedef Archive::AutoDeltaSetObserver<CellPermissions::PermissionObject, CellPermissions::UpdateObserver, BuildingObject> ObservedPermissionObjectSet;
private:
static const SharedObjectTemplate * m_defaultSharedTemplate; // template to use if no shared template is given
// BPM BuildingObject : TangibleObject // Begin persisted members.
Archive::AutoDeltaVariable<int> m_maintenanceCost; ///< The weekly cost (in credits) of maintaining this Building.
Archive::AutoDeltaVariable<real> m_timeLastChecked; ///< The in-game time this Building was last accessed by the player.
Archive::AutoDeltaVariable<int> m_cityId; ///< The player city id this building is assigned to
ObservedBool m_isPublic;
ObservedPermissionObjectSet m_allowed;
ObservedPermissionObjectSet m_banned;
Archive::AutoDeltaVariable<bool> m_contentsLoaded;
// EPM
bool m_checkCreatePortalVolume;
unsigned long m_unloadTime;
};
// ======================================================================
inline int BuildingObject::getMaintenanceCost() const
{
return m_maintenanceCost.get();
}
// ----------------------------------------------------------------------
inline void BuildingObject::setMaintenanceCost(int newConst)
{
m_maintenanceCost = newConst;
}
// ----------------------------------------------------------------------
inline real BuildingObject::getTimeLastChecked() const
{
return m_timeLastChecked.get();
}
// ----------------------------------------------------------------------
inline void BuildingObject::setTimeLastChecked(real newTime)
{
m_timeLastChecked = newTime;
}
// ----------------------------------------------------------------------
inline bool BuildingObject::getIsPublic() const
{
return m_isPublic.get();
}
// ----------------------------------------------------------------------
inline CellPermissions::PermissionList const &BuildingObject::getAllowed() const
{
return m_allowed.get();
}
// ----------------------------------------------------------------------
inline CellPermissions::PermissionList const &BuildingObject::getBanned() const
{
return m_banned.get();
}
// ----------------------------------------------------------------------
inline int BuildingObject::getCityId() const
{
return m_cityId.get();
}
// ----------------------------------------------------------------------
inline bool BuildingObject::getContentsLoaded() const
{
return m_contentsLoaded.get();
}
// ======================================================================
#endif // BuildingObject_H
@@ -0,0 +1,792 @@
// ======================================================================
//
// CellObject.cpp
// Copyright 2001 Sony Online Entertainment
// All Rights Reserved.
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/CellObject.h"
#include "serverGame/BuildingObject.h"
#include "serverGame/CellController.h"
#include "serverGame/Client.h"
#include "serverGame/ConfigServerGame.h"
#include "serverGame/ContainerInterface.h"
#include "serverGame/CreatureObject.h"
#include "serverGame/ServerObjectTemplate.h"
#include "serverGame/ServerTangibleObjectTemplate.h"
#include "serverGame/ServerWorld.h"
#include "serverScript/GameScriptObject.h"
#include "serverScript/ScriptFunctionTable.h"
#include "serverScript/ScriptParameters.h"
#include "sharedCollision/Floor.h"
#include "sharedCollision/FloorMesh.h"
#include "sharedFoundation/ConstCharCrcLowerString.h"
#include "sharedFoundation/DynamicVariableList.h"
#include "sharedLog/Log.h"
#include "sharedNetworkMessages/MessageQueueGenericValueType.h"
#include "sharedNetworkMessages/UpdateCellPermissionMessage.h"
#include "sharedObject/CellProperty.h"
#include "sharedObject/ContainedByProperty.h"
#include "sharedObject/NetworkIdManager.h"
#include "sharedObject/ObjectTemplate.h"
#include "sharedObject/ObjectTemplateList.h"
#include "sharedObject/PortalProperty.h"
#include "sharedPathfinding/PathGraph.h"
#include "sharedPathfinding/PathNode.h"
#include <algorithm>
const SharedObjectTemplate * CellObject::m_defaultSharedTemplate = NULL;
// ======================================================================
CellObject::CellObject(const ServerObjectTemplate *newTemplate)
: ServerObject(newTemplate),
m_cellNumber(-1),
m_isPublic(true),
m_allowed(),
m_banned(),
m_cellLabel(),
m_labelLocationOffset()
{
setDebugName("PortalProperty cell object");
CellProperty *cell = new CellProperty(*this);
addProperty(*cell);
m_isPublic.setSourceObject(this);
m_allowed.setSourceObject(this);
m_banned.setSourceObject(this);
addMembersToPackages();
//@todo -- HACK! this is supposed to be set by the database,
// but that code isn't written. Assume all buildings and cells
// are in the client cache file. //-- it is now [8/4/2002 4:20:48 PM],
// this should be implemented in a few days. If you see this comment
// and the code below calls setIsCachedOnClient(true), get with Chris
// and Calan to determine the status of this code.
//setCacheVersion(1);
}
//-----------------------------------------------------------------------
CellObject::~CellObject()
{
}
//-----------------------------------------------------------------------
Controller * CellObject::createDefaultController()
{
Controller *controller = new CellController(this);
NOT_NULL(controller);
setController(controller);
return controller;
}
//-----------------------------------------------------------------------
/**
* Returns a shared template if none was given for this object.
*
* @return the shared template
*/
const SharedObjectTemplate * CellObject::getDefaultSharedTemplate(void) const
{
static const ConstCharCrcLowerString templateName("object/cell/base/shared_cell_default.iff");
if (m_defaultSharedTemplate == NULL)
{
m_defaultSharedTemplate = safe_cast<const SharedObjectTemplate *>(
ObjectTemplateList::fetch(templateName));
WARNING_STRICT_FATAL(m_defaultSharedTemplate == NULL, ("Cannot create "
"default shared object template %s", templateName.getString()));
if (m_defaultSharedTemplate != NULL)
ExitChain::add (removeDefaultTemplate, "CellObject::removeDefaultTemplate");
}
return m_defaultSharedTemplate;
} // CellObject::getDefaultSharedTemplate
//-----------------------------------------------------------------------
/**
* Cleans up the default shared template.
*/
void CellObject::removeDefaultTemplate(void)
{
if (m_defaultSharedTemplate != NULL)
{
m_defaultSharedTemplate->releaseReference();
m_defaultSharedTemplate = NULL;
}
} // CellObject::removeDefaultTemplate
// ----------------------------------------------------------------------
void CellObject::sendObjectSpecificBaselinesToClient(Client const &client) const
{
ServerObject::sendObjectSpecificBaselinesToClient(client);
ServerObject const * const so = client.getCharacterObject();
if (so)
{
CreatureObject const * const creature = so->asCreatureObject();
if (creature)
{
UpdateCellPermissionMessage message(getNetworkId(), creature ? isAllowed(*creature) : false);
client.send(message, true);
}
}
}
// ----------------------------------------------------------------------
void CellObject::endBaselines()
{
ServerObject::endBaselines();
// fix the load_with values if they don't match
if ( isAuthoritative() && ( getLoadWith() != ContainerInterface::getLoadWithContainerId(*this)))
{
setLoadWith(ContainerInterface::getLoadWithContainerId(*this));
}
DEBUG_FATAL(m_cellNumber.get() < 1, ("Invalid cell number"));
if (m_cellNumber.get() < 1)
{
LOG("CellProblem", ("Invalid cell number for cell %s", getNetworkId().getValueString().c_str()));
}
Object *container = ContainerInterface::getContainedByObject(*this);
PortalProperty *portalProperty = NULL;
if (container)
{
portalProperty = container->getPortalProperty();
}
else
{
ContainedByProperty* prop = ContainerInterface::getContainedByProperty(*this);
LOG("CellProblem",("Cell %s could not resolve contained_by of %s", getNetworkId().getValueString().c_str(), prop->getContainedByNetworkId().getValueString().c_str()));
WARNING(true, ("CellProblem Cell %s could not resolve contained_by of %s", getNetworkId().getValueString().c_str(), prop->getContainedByNetworkId().getValueString().c_str()));
}
if (!portalProperty)
{
LOG("CellProblem",("Cell %s is not inside a POB", getNetworkId().getValueString().c_str()));
WARNING_STRICT_FATAL(true,("Cell %s is not inside a POB.\n",getNetworkId().getValueString().c_str()));
return;
}
if (m_cellNumber.get() < portalProperty->getNumberOfCells())
{
portalProperty->cellLoaded(m_cellNumber.get(), *this, false);
}
else
{
// go through cell contents and remove them all. Give them to the PortalProperty to be fixed when it handles EndBaselines
CellProperty *cellProperty = getCellProperty();
if (cellProperty)
{
for (ContainerIterator contents=cellProperty->begin(); contents != cellProperty->end(); ++contents)
{
Object *object = (*contents).getObject();
portalProperty->queueObjectForFixup(*object);
Container::ContainerErrorCode tmp = Container::CEC_Success;
cellProperty->remove(contents, tmp);
}
}
permanentlyDestroy(DeleteReasons::BadContainerTransfer);
}
#ifdef _DEBUG
if (ConfigServerGame::getDebugFloorPathNodeCount())
{
CellProperty * cellProperty = getCellProperty();
if(cellProperty)
{
Floor const * floor = cellProperty->getFloor();
if(floor)
{
FloorMesh const * floorMesh = floor->getFloorMesh();
NOT_NULL(floorMesh);
PathGraph const * graph = safe_cast<PathGraph const *>(floorMesh->getPathGraph());
if(graph)
{
int floorParts = floorMesh->getPartCount();
int graphParts = graph->getPartCount();
if(floorParts != graphParts)
{
const char * floorName = floorMesh->getName();
WARNING(true,("ServerCollisionProperty::ServerCollisionProperty - floor %s doesn't have the same number of parts as its graph (floor %d, graph %d)",floorName,floorParts,graphParts));
}
}
}
}
}
#endif
}
//-----------------------------------------------------------------------
void CellObject::onLoadedFromDatabase()
{
ServerObject::onLoadedFromDatabase();
// We need to run through the set of banned and allowed players
// and make sure the data is "good".
// - At one time players were stored by name instead of by network ID
ObservedPermissionObjectSet* permissionSets[] = { &m_allowed, &m_banned };
for ( unsigned int i = 0; i < sizeof( permissionSets ) / sizeof( permissionSets[0] ); ++i )
{
const CellPermissions::PermissionList& permList = permissionSets[i]->get();
// Temporary list for processing
CellPermissions::PermissionList tempList;
// On the first pass over the permission list, remove the elements that need to be converted
CellPermissions::PermissionList::const_iterator j;
for ( j = permList.begin(); j != permList.end(); ++j )
{
const CellPermissions::PermissionObject& permObject = (*j);
// Check if the string from the database was valid
if ( !permObject.hasBeenConverted() )
{
// The string in the database needs to be converted
tempList.insert( permObject );
}
}
// Take the elements that need to be converted and re-add them to the list
for ( j = tempList.begin(); j != tempList.end(); ++j )
{
const CellPermissions::PermissionObject& permObject = (*j);
// Remove from the archive set so that it gets marked dirty
permissionSets[i]->erase( permObject );
// Add to the archive set so that it gets marked dirty
// NOTE: The permission object constructor should try to convert the string for us
permissionSets[i]->insert( CellPermissions::PermissionObject( permObject.m_permissionString ) );
}
tempList.clear();
// On the second pass over the permission list, validate all the names
for ( j = permList.begin(); j != permList.end(); ++j )
{
const CellPermissions::PermissionObject& permObject = (*j);
// Make sure we can still obtain a name from the permission object
// For example, characters may have been purged
const std::string name = permObject.getName();
if ( name.empty() )
{
// The entry is no longer valid
tempList.insert( permObject );
}
}
// Remove all the invalid entries
for ( j = tempList.begin(); j != tempList.end(); ++j )
{
const CellPermissions::PermissionObject& permObject = (*j);
// Remove from the archive set so that it gets marked dirty
permissionSets[i]->erase( permObject );
}
tempList.clear();
}
}
// ----------------------------------------------------------------------
void CellObject::addAllowed(std::string const &name)
{
if(isAuthoritative())
{
if (!CellPermissions::isOnList(m_allowed.get(), name))
{
CellPermissions::PermissionObject newPermission(name);
// We don't want to add any permissions that can't be converted to names
if ( !newPermission.getName().empty() )
{
m_allowed.insert(name);
}
}
removeBanned(name);
}
else
{
sendControllerMessageToAuthServer(CM_addAllowed, new MessageQueueGenericValueType<std::string>(name));
}
}
// ----------------------------------------------------------------------
void CellObject::removeAllowed(std::string const &name)
{
if(isAuthoritative())
{
m_allowed.erase(name);
}
else
{
sendControllerMessageToAuthServer(CM_removeAllowed, new MessageQueueGenericValueType<std::string>(name));
}
}
// ----------------------------------------------------------------------
void CellObject::removeAllAllowed()
{
if(isAuthoritative())
{
m_allowed.clear();
}
else
{
sendControllerMessageToAuthServer(CM_removeAllAllowed, 0);
}
}
// ----------------------------------------------------------------------
void CellObject::addBanned(std::string const &name)
{
if(isAuthoritative())
{
if (!CellPermissions::isOnList(m_banned.get(), name))
{
CellPermissions::PermissionObject newPermission(name);
// We don't want to add any permissions that can't be converted to names
if ( !newPermission.getName().empty() )
{
m_banned.insert(name);
}
}
removeAllowed(name);
}
else
{
sendControllerMessageToAuthServer(CM_addBanned, new MessageQueueGenericValueType<std::string>(name));
}
}
// ----------------------------------------------------------------------
void CellObject::removeBanned(std::string const &name)
{
if(isAuthoritative())
{
m_banned.erase(name);
}
else
{
sendControllerMessageToAuthServer(CM_removeBanned, new MessageQueueGenericValueType<std::string>(name));
}
}
// ----------------------------------------------------------------------
void CellObject::removeAllBanned()
{
if(isAuthoritative())
{
m_banned.clear();
}
else
{
sendControllerMessageToAuthServer(CM_removeAllBanned, 0);
}
}
// ----------------------------------------------------------------------
ServerObject const *CellObject::getOwner() const
{
Object const * const o = ContainerInterface::getContainedByObject(*this);
if (o)
return o->asServerObject();
return 0;
}
// ----------------------------------------------------------------------
ServerObject *CellObject::getOwner()
{
Object * const o = ContainerInterface::getContainedByObject(*this);
if (o)
return o->asServerObject();
return 0;
}
// ----------------------------------------------------------------------
BuildingObject const *CellObject::getOwnerBuilding() const
{
Object const * const o = ContainerInterface::getContainedByObject(*this);
if (o)
{
ServerObject const * const so = o->asServerObject();
if (so)
return so->asBuildingObject();
}
return 0;
}
// ----------------------------------------------------------------------
BuildingObject *CellObject::getOwnerBuilding()
{
Object * const o = ContainerInterface::getContainedByObject(*this);
if (o)
{
ServerObject * const so = o->asServerObject();
if (so)
return so->asBuildingObject();
}
return 0;
}
// ----------------------------------------------------------------------
ShipObject const *CellObject::getOwnerShip() const
{
Object const * const o = ContainerInterface::getContainedByObject(*this);
if (o)
{
ServerObject const * const so = o->asServerObject();
if (so)
return so->asShipObject();
}
return 0;
}
// ----------------------------------------------------------------------
ShipObject *CellObject::getOwnerShip()
{
Object * const o = ContainerInterface::getContainedByObject(*this);
if (o)
{
ServerObject * const so = o->asServerObject();
if (so)
return so->asShipObject();
}
return 0;
}
// ----------------------------------------------------------------------
bool CellObject::isAllowed(CreatureObject const &who) const
{
if (who.getMasterId() != NetworkId::cms_invalid)
{
ServerObject const *master = ServerWorld::findObjectByNetworkId(who.getMasterId());
if (master && master != &who && master->asCreatureObject())
return isAllowed(*master->asCreatureObject());
}
BuildingObject const *building = getOwnerBuilding();
if (building)
{
if (!building->playersWithAlignedEnemyFlagsAllowed() && (Pvp::hasAnyAlignedTimedEnemyFlag(who) || Pvp::hasAnyBountyDuelEnemyFlag(who)))
return false;
if (building->isOwner(who.getNetworkId(), who.getClient()))
return true;
if (!building->isAllowed(who))
return false;
}
if (getIsPublic())
return !CellPermissions::isOnList(m_banned.get(), who);
else
{
// allow non-player-controlled creatures in private buildings with no owner
if (!who.isPlayerControlled() && building && building->getOwnerId() == NetworkId::cms_invalid)
return true;
// allow vendor-creatures to be placed in the building
if (who.hasCondition(ServerTangibleObjectTemplate::C_vendor))
return true;
return CellPermissions::isOnList(m_allowed.get(), who);
}
}
// ----------------------------------------------------------------------
bool CellObject::getClosestPathNodePos( const ServerObject & object, Vector & outPos ) const
{
const PathNode * closestNode = NULL;
float closestDistance = 0;
const Vector objectPos = object.getPosition_w();
const CellProperty * cell = ContainerInterface::getCell(*this);
if (cell != NULL)
{
const Floor * floor = cell->getFloor();
if (floor != NULL)
{
const FloorMesh * mesh = floor->getFloorMesh();
if (mesh != NULL)
{
const PathGraph * path = safe_cast<const PathGraph *>(mesh->getPathGraph());
if (path != NULL)
{
int nodeCount = path->getNodeCount();
for (int i = 0; i < nodeCount; ++i)
{
const PathNode * node = path->getNode(i);
if (node != NULL)
{
float distance = objectPos.magnitudeBetweenSquared(
rotateTranslate_p2w(node->getPosition_p()));
if (closestNode == NULL || distance < closestDistance)
{
closestNode = node;
closestDistance = distance;
}
}
}
}
}
}
}
if (closestNode != NULL)
outPos = closestNode->getPosition_p();
return closestNode != NULL;
}
// ----------------------------------------------------------------------
bool CellObject::isVisibleOnClient (const Client & /*client*/) const
{
return true;
}
// ----------------------------------------------------------------------
void CellObject::getAttributes (stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const
{
ServerObject::getAttributes(data);
}
// ----------------------------------------------------------------------
bool CellObject::onContainerAboutToLoseItem(ServerObject * destination, ServerObject& item, ServerObject* transferer)
{
//Cells should first check to see if the building will allow the item to be transfered.
ServerObject *obj = getOwner();
if (obj)
{
ScriptParams params;
params.addParam(destination ? destination->getNetworkId() : NetworkId::cms_invalid);
params.addParam(transferer ? transferer->getNetworkId() : NetworkId::cms_invalid);
params.addParam(item.getNetworkId());
if(obj->getScriptObject()->trigAllScripts(Scripting::TRIG_ABOUT_TO_LOSE_ITEM, params) == SCRIPT_OVERRIDE)
{
return false;
}
}
return ServerObject::onContainerAboutToLoseItem(destination, item, transferer);
}
// ----------------------------------------------------------------------
int CellObject::onContainerAboutToGainItem(ServerObject& item, ServerObject* transferer)
{
// If it's a creature trying to move into the cell, see if it's allowed.
CreatureObject * const creatureItem = item.asCreatureObject();
if (creatureItem && !isAllowed(*creatureItem))
return Container::CEC_SilentError;
//Cells should first check to see if the building will allow the item to be transfered.
ServerObject *obj = getOwner();
if (obj)
{
ServerObject const * const source = safe_cast<ServerObject const *>(ContainerInterface::getContainedByObject(item));
NetworkId sourceId = source ? source->getNetworkId() : NetworkId::cms_invalid;
ScriptParams params;
params.addParam(sourceId);
params.addParam(transferer ? transferer->getNetworkId() : NetworkId::cms_invalid);
params.addParam(item.getNetworkId());
if (obj->getScriptObject()->trigAllScripts(Scripting::TRIG_ABOUT_TO_RECEIVE_ITEM, params) == SCRIPT_OVERRIDE)
return Container::CEC_BlockedByScript;
}
return ServerObject::onContainerAboutToGainItem(item, transferer);
}
// ----------------------------------------------------------------------
void CellObject::onContainerLostItem(ServerObject * destination, ServerObject& item, ServerObject* transferer)
{
//Cells should first check to see if the building will allow the item to be transfered.
ServerObject * const obj = getOwner();
if (obj)
{
ScriptParams params;
params.addParam(destination ? destination->getNetworkId() : NetworkId::cms_invalid);
params.addParam(transferer ? transferer->getNetworkId() : NetworkId::cms_invalid);
params.addParam(item.getNetworkId());
obj->getScriptObject()->trigAllScripts(Scripting::TRIG_LOST_ITEM, params);
BuildingObject * const b_obj = getOwnerBuilding();
if (b_obj && item.isPlayerControlled() && destination == NULL)
{
b_obj->lostPlayer(item);
}
}
ServerObject::onContainerLostItem(destination, item, transferer);
}
// ----------------------------------------------------------------------
void CellObject::onContainerGainItem(ServerObject& item, ServerObject * source, ServerObject* transferer)
{
//Cells should first check to see if the building will allow the item to be transfered.
ServerObject * const obj = getOwner();
if (obj)
{
// The default owner of an object in a building is the building's owner, unless it is a creature, ship, or vendor
if ( !item.asCreatureObject()
&& !item.asShipObject()
&& !item.isVendor())
{
item.setOwnerId(obj->getOwnerId());
}
ScriptParams params;
params.addParam(source ? source->getNetworkId() : NetworkId::cms_invalid);
params.addParam(transferer ? transferer->getNetworkId() : NetworkId::cms_invalid);
params.addParam(item.getNetworkId());
obj->getScriptObject()->trigAllScripts(Scripting::TRIG_RECEIVED_ITEM, params);
BuildingObject * const b_obj = getOwnerBuilding();
if (b_obj && item.isPlayerControlled() && !source)
{
b_obj->gainedPlayer(item);
}
}
ServerObject::onContainerGainItem(item, source, transferer);
}
// ----------------------------------------------------------------------
NetworkId const &CellObject::getOwnerId() const
{
Object const * const o = ContainerInterface::getContainedByObject(*this);
if (o)
{
ServerObject const * const so = o->asServerObject();
if (so)
return so->getOwnerId();
}
return NetworkId::cms_invalid;
}
// ----------------------------------------------------------------------
bool CellObject::isOwner(NetworkId const &id, Client const *client) const
{
Object const * const o = ContainerInterface::getContainedByObject(*this);
if (o)
{
ServerObject const * const so = o->asServerObject();
if (so)
return so->isOwner(id, client);
}
return false;
}
// ----------------------------------------------------------------------
void CellObject::setOwnerId(NetworkId const &id)
{
if (isAuthoritative())
{
Container * const container = ContainerInterface::getContainer(*this);
if (container)
{
for (ContainerIterator i = container->begin(); i != container->end(); ++i)
{
ServerObject * const content = safe_cast<ServerObject *>((*i).getObject());
if (content && !content->asCreatureObject())
content->setOwnerId(id);
}
}
}
//if not authoritative, that's ok. This should only be called when the authoritative building has setOwnerId called on it.
}
// ----------------------------------------------------------------------
void CellObject::onAllContentsLoaded()
{
ServerObject::onAllContentsLoaded();
BuildingObject * owner = getOwnerBuilding();
if (owner)
owner->onCellContentsLoaded();
}
// ----------------------------------------------------------------------
CellObject * CellObject::asCellObject()
{
return this;
}
// ----------------------------------------------------------------------
CellObject const * CellObject::asCellObject() const
{
return this;
}
// ----------------------------------------------------------------------
CellObject * CellObject::getCellObject(NetworkId const & networkId)
{
return CellObject::asCellObject(NetworkIdManager::getObjectById(networkId));
}
// ----------------------------------------------------------------------
CellObject * CellObject::asCellObject(Object * object)
{
ServerObject * const serverObject = (object != NULL) ? object->asServerObject() : NULL;
CellObject * const cellObject = (serverObject != NULL) ? serverObject->asCellObject() : NULL;
return cellObject;
}
// ----------------------------------------------------------------------
CellObject const * CellObject::asCellObject(Object const * object)
{
ServerObject const * const serverObject = (object != NULL) ? object->asServerObject() : NULL;
CellObject const * const cellObject = (serverObject != NULL) ? serverObject->asCellObject() : NULL;
return cellObject;
}
// ======================================================================
@@ -0,0 +1,187 @@
// ======================================================================
//
// CellObject.h
// Copyright 2001 Sony Online Entertainment
// All Rights Reserved.
//
// ======================================================================
#ifndef INCLUDED_CellObject_H
#define INCLUDED_CellObject_H
// ======================================================================
#include "serverGame/ServerObject.h"
#include "serverGame/CellPermissions.h"
#include "Archive/AutoDeltaVariableObserver.h"
#include "Archive/AutoDeltaSetObserver.h"
// ======================================================================
class BuildingObject;
class CreatureObject;
// ======================================================================
class CellObject : public ServerObject
{
public:
static CellObject * getCellObject(NetworkId const & networkId);
static CellObject * asCellObject(Object * object);
static CellObject const * asCellObject(Object const * objec);
public:
explicit CellObject(const ServerObjectTemplate *newTemplate);
virtual ~CellObject();
virtual CellObject *asCellObject();
virtual CellObject const *asCellObject() const;
static void removeDefaultTemplate(void);
virtual Controller * createDefaultController();
void setCell(int cellNumber);
int getCell() const;
void setIsPublic(bool isPublic);
bool getIsPublic() const;
void addAllowed(std::string const &name);
void removeAllowed(std::string const &name);
void removeAllAllowed();
void addBanned(std::string const &name);
void removeBanned(std::string const &name);
void removeAllBanned();
CellPermissions::PermissionList const &getAllowed() const;
CellPermissions::PermissionList const &getBanned() const;
Unicode::String const & getCellLabel() const;
void setCellLabel(Unicode::String const & label);
Vector const & getLabelLocationOffset() const;
void setLabelLocationOffset(Vector const & offset);
bool getClosestPathNodePos( const ServerObject & object, Vector & outPos ) const;
ServerObject * getOwner();
ServerObject const * getOwner() const;
BuildingObject * getOwnerBuilding();
BuildingObject const * getOwnerBuilding() const;
ShipObject * getOwnerShip();
ShipObject const * getOwnerShip() const;
bool isAllowed(CreatureObject const &who) const;
virtual bool isVisibleOnClient (const Client & client) const;
void addMembersToPackages();
virtual void getAttributes (stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const;
virtual const NetworkId & getOwnerId() const;
virtual bool isOwner(NetworkId const &id, Client const *client) const;
virtual void setOwnerId(const NetworkId &id);
virtual void sendObjectSpecificBaselinesToClient(Client const &client) const;
//Container triggers for notifiying the building
virtual bool onContainerAboutToLoseItem(ServerObject * destination, ServerObject& item, ServerObject* transferer);
virtual int onContainerAboutToGainItem(ServerObject& item, ServerObject* transferer);
virtual void onContainerLostItem(ServerObject * destination, ServerObject& item, ServerObject* transferer);
virtual void onContainerGainItem(ServerObject& item, ServerObject* source, ServerObject* transferer);
virtual void onAllContentsLoaded();
protected:
virtual void endBaselines();
virtual void onLoadedFromDatabase();
virtual const SharedObjectTemplate * getDefaultSharedTemplate(void) const;
private:
CellObject();
CellObject(const CellObject &);
CellObject &operator =(const CellObject &);
typedef Archive::AutoDeltaVariableObserver<bool, CellPermissions::UpdateObserver, CellObject> ObservedBool;
typedef Archive::AutoDeltaSetObserver<CellPermissions::PermissionObject, CellPermissions::UpdateObserver, CellObject> ObservedPermissionObjectSet;
private:
static const SharedObjectTemplate * m_defaultSharedTemplate; // template to use if no shared template is given
Archive::AutoDeltaVariable<int> m_cellNumber;
ObservedBool m_isPublic;
ObservedPermissionObjectSet m_allowed;
ObservedPermissionObjectSet m_banned;
Archive::AutoDeltaVariable<Unicode::String> m_cellLabel;
Archive::AutoDeltaVariable<Vector> m_labelLocationOffset;
};
// ======================================================================
inline void CellObject::setCell(int cellNumber)
{
m_cellNumber = cellNumber;
}
// ----------------------------------------------------------------------
inline int CellObject::getCell() const
{
return m_cellNumber.get();
}
// ----------------------------------------------------------------------
inline bool CellObject::getIsPublic() const
{
return m_isPublic.get();
}
// ----------------------------------------------------------------------
inline void CellObject::setIsPublic(bool isPublic)
{
m_isPublic.set(isPublic);
}
// ----------------------------------------------------------------------
inline CellPermissions::PermissionList const &CellObject::getAllowed() const
{
return m_allowed.get();
}
// ----------------------------------------------------------------------
inline CellPermissions::PermissionList const &CellObject::getBanned() const
{
return m_banned.get();
}
// ----------------------------------------------------------------------
inline Unicode::String const & CellObject::getCellLabel() const
{
return m_cellLabel.get();
}
// ----------------------------------------------------------------------
inline void CellObject::setCellLabel(Unicode::String const & label)
{
m_cellLabel.set(label);
}
// ----------------------------------------------------------------------
inline Vector const & CellObject::getLabelLocationOffset() const
{
return m_labelLocationOffset.get();
}
// ----------------------------------------------------------------------
inline void CellObject::setLabelLocationOffset(Vector const & offset)
{
m_labelLocationOffset.set(offset);
}
// ======================================================================
#endif
@@ -0,0 +1,510 @@
// ======================================================================
//
// CellPermissions.cpp
//
// Copyright 2002 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/CellPermissions.h"
#include "UnicodeUtils.h"
#include "serverGame/BuildingObject.h"
#include "serverGame/CellObject.h"
#include "serverGame/Client.h"
#include "serverGame/ContainerInterface.h"
#include "serverGame/CreatureObject.h"
#include "serverGame/GuildInterface.h"
#include "serverGame/NameManager.h"
#include "sharedFoundation/NetworkId.h"
#include "sharedLog/Log.h"
#include "sharedObject/Container.h"
#include "sharedNetworkMessages/UpdateCellPermissionMessage.h"
// ======================================================================
static std::set<BuildingObject const*> s_activeUpdaters;
// ======================================================================
namespace Archive
{
// The prefixes we use to write permission strings to the database
const std::string PERMISSION_STRING_PREFIX_UNKNOWN_OLD = "u:";
const std::string PERMISSION_STRING_PREFIX_UNKNOWN_NEW = "U:";
const std::string PERMISSION_STRING_PREFIX_GUILD_NAME_OLD = "g:";
const std::string PERMISSION_STRING_PREFIX_GUILD_NAME_NEW = "G:";
const std::string PERMISSION_STRING_PREFIX_CHARACTER_NAME = "c:";
const std::string PERMISSION_STRING_PREFIX_NUMERIC_VALUE = "n:";
// ----------------------------------------------------------------------
void get(ReadIterator &source, CellPermissions::PermissionObject &target)
{
std::string permissionString;
get(source, permissionString);
// Assume the string in the database has not been converted
CellPermissions::PermissionObject::PermissionFormat format = CellPermissions::PermissionObject::PF_UNCONVERTED;
// Determine whether the string in the database has already been converted
const std::string prefix( permissionString, 0, 2 );
if ( prefix == PERMISSION_STRING_PREFIX_CHARACTER_NAME )
{
format = CellPermissions::PermissionObject::PF_CHARACTER_NAME;
}
else if ( prefix == PERMISSION_STRING_PREFIX_GUILD_NAME_OLD )
{
// We used to store guilds by name instead of guild ID.
// So we will try to reconvert the guild name to a guild ID
format = CellPermissions::PermissionObject::PF_UNCONVERTED;
permissionString.erase( 0, prefix.length() );
}
else if ( prefix == PERMISSION_STRING_PREFIX_GUILD_NAME_NEW )
{
format = CellPermissions::PermissionObject::PF_GUILD_NAME;
}
else if ( prefix == PERMISSION_STRING_PREFIX_NUMERIC_VALUE )
{
format = CellPermissions::PermissionObject::PF_NUMERIC_VALUE;
}
else if ( prefix == PERMISSION_STRING_PREFIX_UNKNOWN_OLD )
{
// We had an issue where we may have been storing full names in the database
// and we did not know they were player names since NameManager only
// converts first names to player names. So we will try to reconvert
// the unknown entries again
format = CellPermissions::PermissionObject::PF_UNCONVERTED;
permissionString.erase( 0, prefix.length() );
}
else if ( prefix == PERMISSION_STRING_PREFIX_UNKNOWN_NEW )
{
format = CellPermissions::PermissionObject::PF_UNKNOWN_STRING;
}
// Remove the prefix if necessary
if ( format != CellPermissions::PermissionObject::PF_UNCONVERTED )
{
permissionString.erase( 0, prefix.length() );
}
// When buildings and cells load, it is their responsibility to convert the string if necessary
target = CellPermissions::PermissionObject( format, permissionString );
}
// ----------------------------------------------------------------------
void put( ByteStream &target, CellPermissions::PermissionObject const &source )
{
std::string permissionString = source.m_permissionString;
// Before writing out the permission string, we need to append a prefix
switch ( source.m_originalPermissionFormat )
{
case CellPermissions::PermissionObject::PF_CHARACTER_NAME:
permissionString = PERMISSION_STRING_PREFIX_CHARACTER_NAME + permissionString;
break;
case CellPermissions::PermissionObject::PF_GUILD_NAME:
permissionString = PERMISSION_STRING_PREFIX_GUILD_NAME_NEW + permissionString;
break;
case CellPermissions::PermissionObject::PF_NUMERIC_VALUE:
permissionString = PERMISSION_STRING_PREFIX_NUMERIC_VALUE + permissionString;
break;
case CellPermissions::PermissionObject::PF_UNKNOWN_STRING:
permissionString = PERMISSION_STRING_PREFIX_UNKNOWN_NEW + permissionString;
break;
default:
// Do nothing to the string and it will be considered "unconverted" when it is read back in
break;
}
put(target, permissionString);
}
}; // namespace Archive
// ======================================================================
CellPermissions::PermissionObject::PermissionObject() :
m_originalPermissionFormat( PF_UNCONVERTED ),
m_permissionString()
{
}
// ----------------------------------------------------------------------
CellPermissions::PermissionObject::PermissionObject( const std::string& name ) :
m_originalPermissionFormat( PF_UNKNOWN_STRING ),
m_permissionString( Unicode::getTrim(name) )
{
// See if we have a guild name
if (_strnicmp( name.c_str(), "Guild:", 6 ) == 0 )
{
// Try to convert the name to a guild ID
int guildId = GuildInterface::findGuild( Unicode::getTrim((name).substr(6)) );
if ( guildId != 0 )
{
// Convert the guild ID to a string
char buffer[32];
sprintf( buffer, "%d", guildId );
m_originalPermissionFormat = PF_GUILD_NAME;
m_permissionString = buffer;
}
else
{
// We will leave the format as "unknown" and keep the raw string
}
}
else
{
// The name string might be an actual name or a network ID...
// See if there are any characters in the string
std::string::size_type idx = name.find_first_not_of( "1234567890" );
if ( idx == std::string::npos )
{
// Everything in the string is a number
m_originalPermissionFormat = PF_NUMERIC_VALUE;
m_permissionString = name;
}
else
{
// Try to convert the name to a network ID
const NetworkId playerNetworkId = NameManager::getInstance().getPlayerId( NameManager::normalizeName( name ) );
if ( playerNetworkId != NetworkId::cms_invalid )
{
// We found the network ID for the player
m_originalPermissionFormat = PF_CHARACTER_NAME;
m_permissionString = playerNetworkId.getValueString();
}
else
{
// We will leave the format as "unknown" and keep the raw string
}
}
}
}
// ----------------------------------------------------------------------
CellPermissions::PermissionObject::PermissionObject( PermissionFormat format, const std::string& name ) :
m_originalPermissionFormat( format ),
m_permissionString( name )
{
}
// ----------------------------------------------------------------------
bool CellPermissions::PermissionObject::operator<(PermissionObject const &rhs) const
{
return (m_permissionString < rhs.m_permissionString);
}
// ----------------------------------------------------------------------
std::string CellPermissions::PermissionObject::getName() const
{
std::string nameString;
// Depending on the original format, we may need to convert the permission string
switch ( m_originalPermissionFormat )
{
case PF_CHARACTER_NAME:
{
const NetworkId playerNetworkId = NetworkId( m_permissionString );
// Try to convert the network ID to an actual player name
// NOTE: We grab the full name so that capitalization is correct
const std::string fullName = NameManager::getInstance().getPlayerFullName( playerNetworkId );
// Parse the first name from the full name
size_t curpos = 0;
std::string firstName;
if ( Unicode::getFirstToken( fullName, curpos, curpos, firstName ) )
{
nameString = firstName;
}
}
break;
case PF_GUILD_NAME:
{
const int guildId = atoi( m_permissionString.c_str() );
// Try to convert the guildId to an actual guild name
if ( guildId != 0 )
{
// Prefix with "Guild: " for legacy reasons
nameString = "Guild:" + GuildInterface::getGuildAbbrev( guildId );
}
}
break;
case PF_NUMERIC_VALUE:
case PF_UNKNOWN_STRING:
default:
// Just return the stored string for these cases
nameString = m_permissionString;
break;
}
return nameString;
}
// ----------------------------------------------------------------------
bool CellPermissions::PermissionObject::hasBeenConverted() const
{
return (m_originalPermissionFormat != PF_UNCONVERTED);
}
// ======================================================================
CellPermissions::UpdateObserver::UpdateObserver(CellObject *cell, Archive::AutoDeltaObserverOp) :
m_profilerBlock("CellPermissions::UpdateObserver - cell"),
m_building(0),
m_permissions()
{
if (cell)
{
BuildingObject *building = cell->getOwnerBuilding();
if (building)
init(building);
}
}
// ----------------------------------------------------------------------
CellPermissions::UpdateObserver::UpdateObserver(TangibleObject *tangible, Archive::AutoDeltaObserverOp) :
m_profilerBlock("CellPermissions::UpdateObserver - building"),
m_building(0),
m_permissions()
{
if (tangible)
{
BuildingObject * const building = tangible->asBuildingObject();
if (building)
init(building);
}
}
// ----------------------------------------------------------------------
CellPermissions::UpdateObserver::~UpdateObserver()
{
if (m_building)
{
s_activeUpdaters.erase(m_building);
// send permission updates for any changes to any cells of this building,
// and collect list of creatures we need to expel due to these changes.
unsigned int permPos = 0;
std::vector<CreatureObject*> expel;
handleCellPermissionsUpdateIfNeeded(*m_building, permPos, expel);
// expel any creatures from the building that no longer belong.
for (std::vector<CreatureObject*>::const_iterator i = expel.begin(); i != expel.end(); ++i)
m_building->expelObject(**i);
}
}
// ----------------------------------------------------------------------
void CellPermissions::UpdateObserver::init(BuildingObject *building)
{
if (!building || s_activeUpdaters.find(building) != s_activeUpdaters.end())
return;
m_building = building;
s_activeUpdaters.insert(building);
// get permissions for all observers for all cells of this building
getCellPermissions(*building);
}
// ----------------------------------------------------------------------
void CellPermissions::UpdateObserver::getCellPermissions(ServerObject &obj)
{
Container * const container = ContainerInterface::getContainer(obj);
if (container)
{
for (ContainerIterator i = container->begin(); i != container->end(); ++i)
{
ServerObject * const content = safe_cast<ServerObject*>((*i).getObject());
if (content)
{
CellObject * const cell = content->asCellObject();
if (cell)
{
std::set<Client *> const &observers = m_building->getObservers();
for (std::set<Client *>::const_iterator j = observers.begin(); j != observers.end(); ++j)
{
ServerObject * const so = (*j)->getCharacterObject();
if (so)
{
CreatureObject * const creature = so->asCreatureObject();
if (creature)
m_permissions.push_back(cell->isAllowed(*creature));
}
}
}
getCellPermissions(*content);
}
}
}
}
// ----------------------------------------------------------------------
void CellPermissions::UpdateObserver::handleCellPermissionsUpdateIfNeeded(ServerObject &obj, unsigned int &permPos, std::vector<CreatureObject*> &expel)
{
Container *container = ContainerInterface::getContainer(obj);
if (container)
{
for (ContainerIterator i = container->begin(); i != container->end(); ++i)
{
ServerObject * const content = safe_cast<ServerObject *>((*i).getObject());
if (content)
{
CellObject * const cell = content->asCellObject();
if (cell)
{
std::set<Client *> const &observers = m_building->getObservers();
for (std::set<Client *>::const_iterator j = observers.begin(); j != observers.end(); ++j)
{
ServerObject * const so = (*j)->getCharacterObject();
if (so)
{
CreatureObject * const creature = so->asCreatureObject();
if (creature)
{
bool const allowed = cell->isAllowed(*creature);
if (allowed != m_permissions[permPos])
{
LOG("CellPermUpdate", ("sending UpdateCellPermission for %s to client %s (%d)",
cell->getNetworkId().getValueString().c_str(),
(*j)->getCharacterObjectId().getValueString().c_str(),
allowed ? 1 : 0));
UpdateCellPermissionMessage const message(cell->getNetworkId(), allowed);
(*j)->send(message, true);
}
if (!allowed && creature->getAttachedTo() == cell)
expel.push_back(creature);
++permPos;
}
}
}
}
handleCellPermissionsUpdateIfNeeded(*content, permPos, expel);
}
}
}
}
// ======================================================================
CellPermissions::ViewerChangeObserver::ViewerChangeObserver(CreatureObject *creature) :
m_profilerBlock("CellPermissions::ViewerChangeObserver"),
m_cells(),
m_permissions(),
m_creature(creature)
{
if (creature)
{
Client * const client = creature->getClient();
if (client)
{
Client::ObservingList const &observing = client->getObserving();
for (Client::ObservingList::const_iterator i = observing.begin(); i != observing.end(); ++i)
{
CellObject * const cell = (*i)->asCellObject();
if (cell)
{
m_cells.push_back(cell);
m_permissions.push_back(cell->isAllowed(*creature));
}
}
}
}
}
// ----------------------------------------------------------------------
CellPermissions::ViewerChangeObserver::~ViewerChangeObserver()
{
if (!m_creature)
return;
// send any needed permission updates
Client * const client = m_creature->getClient();
if (client)
{
for (unsigned int i = 0; i < m_cells.size(); ++i)
{
bool const allowed = m_cells[i]->isAllowed(*m_creature);
if (allowed != m_permissions[i])
{
UpdateCellPermissionMessage const message(m_cells[i]->getNetworkId(), allowed);
client->send(message, true);
}
}
}
// expel from the current building if they're not allowed in anymore
CellObject * const cell = ContainerInterface::getContainingCellObject(*m_creature);
if (cell && !cell->isAllowed(*m_creature))
{
BuildingObject * const building = cell->getOwnerBuilding();
if (building)
building->expelObject(*m_creature);
}
}
// ======================================================================
bool CellPermissions::isOnList(PermissionList const &permList, std::string const &name) // static
{
for (PermissionList::const_iterator i = permList.begin(); i != permList.end(); ++i)
if (!_stricmp((*i).getName().c_str(), name.c_str()))
return true;
return false;
}
// ----------------------------------------------------------------------
bool CellPermissions::isOnList(PermissionList const &permList, CreatureObject const &who) // static
{
const int guildId = who.getGuildId();
// if either their name or their guild is on the list, consider them on the list
for (PermissionList::const_iterator i = permList.begin(); i != permList.end(); ++i)
{
const std::string& name = (*i).getName();
// objectId
if (name == who.getNetworkId().getValueString())
return true;
// first name
if (!_stricmp(name.c_str(), Unicode::wideToNarrow(who.getAssignedObjectFirstName()).c_str()))
return true;
// guilds
if (guildId && !_strnicmp(name.c_str(), "Guild:", 6))
{
std::string checkStr(Unicode::getTrim((name).substr(6)));
if ( !_stricmp(checkStr.c_str(), GuildInterface::getGuildAbbrev(guildId).c_str())
|| !_stricmp(checkStr.c_str(), GuildInterface::getGuildName(guildId).c_str()))
return true;
}
}
return false;
}
// ======================================================================
@@ -0,0 +1,150 @@
// ======================================================================
//
// CellPermsUpdateObserver.h
//
// Copyright 2002 Sony Online Entertainment
//
// ======================================================================
#ifndef CellPermissions_H
#define CellPermissions_H
// ======================================================================
#include "Archive/AutoDeltaObserverOps.h"
#include "Archive/ByteStream.h"
#include "sharedDebug/Profiler.h"
// ======================================================================
class BuildingObject;
class CellObject;
class Client;
class CreatureObject;
class NetworkId;
class ServerObject;
class TangibleObject;
// ======================================================================
namespace CellPermissions
{
class PermissionObject;
};
//----------------------------------------------------------------------
namespace Archive
{
void get(ReadIterator & source, CellPermissions::PermissionObject & target);
void put(ByteStream & target, const CellPermissions::PermissionObject & source);
};
//----------------------------------------------------------------------
namespace CellPermissions
{
//----------------------------------------------------------------------
class PermissionObject
{
friend void Archive::get( ReadIterator & source, CellPermissions::PermissionObject & target );
friend void Archive::put( ByteStream & target, const CellPermissions::PermissionObject & source );
friend class BuildingObject;
friend class CellObject;
public:
PermissionObject();
PermissionObject( const std::string& name );
bool operator<( PermissionObject const &rhs ) const;
// Return the permission string in the same format as it was given
std::string getName() const;
private:
// We need to remember the "format" of the string that was given to us
enum PermissionFormat
{
PF_UNCONVERTED, // A string read from the database that has not been converted
PF_CHARACTER_NAME, // A string was given that we could convert to a network ID
PF_GUILD_NAME, // A guild name was provided
PF_NUMERIC_VALUE, // A numeric value was given to us (probably a network ID)
PF_UNKNOWN_STRING, // A string was given to us that doesn't fit the other categories
};
// Intended to be used for converting entries from the database
PermissionObject( PermissionFormat format, const std::string& name );
private:
// Query whether the permission string has ever been "converted"
// NOTE: This is intended to let Building and Cell objects know whether
// they need to convert data that has been loaded from the database.
bool hasBeenConverted() const;
private:
PermissionFormat m_originalPermissionFormat;
std::string m_permissionString;
};
typedef stdset<PermissionObject>::fwd PermissionList;
//----------------------------------------------------------------------
class UpdateObserver
{
public:
UpdateObserver(CellObject *cell, Archive::AutoDeltaObserverOp operation);
UpdateObserver(TangibleObject *tangible, Archive::AutoDeltaObserverOp operation);
~UpdateObserver();
private:
UpdateObserver(UpdateObserver const &);
UpdateObserver &operator=(UpdateObserver const &);
void init(BuildingObject *building);
void getCellPermissions(ServerObject &obj);
void handleCellPermissionsUpdateIfNeeded(ServerObject &obj, unsigned int &permPos, stdvector<CreatureObject*>::fwd &expel);
private:
ProfilerAutoBlock m_profilerBlock;
BuildingObject * m_building;
std::vector<bool> m_permissions;
};
//----------------------------------------------------------------------
class ViewerChangeObserver
{
public:
ViewerChangeObserver(CreatureObject *creature);
~ViewerChangeObserver();
private:
ViewerChangeObserver(ViewerChangeObserver const &);
ViewerChangeObserver &operator=(ViewerChangeObserver const &);
private:
ProfilerAutoBlock m_profilerBlock;
std::vector<CellObject *> m_cells;
std::vector<bool> m_permissions;
CreatureObject *m_creature;
};
//----------------------------------------------------------------------
bool isOnList(PermissionList const &permList, std::string const &name);
bool isOnList(PermissionList const &permList, CreatureObject const &who);
//----------------------------------------------------------------------
};
// ======================================================================
#endif // CellPermissions_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,160 @@
//========================================================================
//
// CityObject.h
//
// Copyright 2003 Sony Online Entertainment
//
//========================================================================
#ifndef INCLUDED_CityObject_H
#define INCLUDED_CityObject_H
// ======================================================================
#include "Archive/AutoDeltaSet.h"
#include "serverGame/CitizenInfo.h"
#include "serverGame/CityInfo.h"
#include "serverGame/CityStructureInfo.h"
#include "serverGame/PgcRatingInfo.h"
#include "serverGame/UniverseObject.h"
// ======================================================================
class ServerCityObjectTemplate;
// ======================================================================
class CityObject: public UniverseObject
{
public:
CityObject(ServerCityObjectTemplate const *newTemplate);
virtual ~CityObject();
virtual Controller* createDefaultController();
virtual void setupUniverse();
virtual void getAttributes(stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const;
virtual void unload();
int createCity(std::string const &cityName, NetworkId const &cityHallId, std::string const &cityPlanet, int x, int z, int radius, NetworkId const &leaderId, int incomeTax, int propertyTax, int salesTax, Vector const &travelLoc, int travelCost, bool travelInterplanetary, Vector const &cloneLoc, Vector const &cloneRespawn, NetworkId const &cloneRespawnCell, NetworkId const &cloneId, int cityId = 0);
void removeCity(int cityId);
void removeCitizen(int cityId, NetworkId const &citizenId);
void removeCityStructure(int cityId, NetworkId const &structureId);
void setCityName(int cityId, std::string const &cityName);
void setCityHall(int cityId, NetworkId const &cityHallId);
void setCityLocation(int cityId, std::string const &cityPlanet, int x, int z);
void setCityRadius(int cityId, int radius);
void setCityFaction(int cityId, uint32 faction, bool notifyCitizens);
void setCityGcwDefenderRegion(int cityId, std::string const &gcwDefenderRegion, int timeJoined, bool notifyCitizens);
void setCityCreationTime(int cityId, int creationTime);
void setCityLeader(int cityId, NetworkId const &leaderId);
void setCityIncomeTax(int cityId, int incomeTax);
void setCityPropertyTax(int cityId, int propertyTax);
void setCitySalesTax(int cityId, int salesTax);
void setCityTravelInfo(int cityId, Vector const &travelLoc, int travelCost, bool travelInterplanetary);
void setCityCloneInfo(int cityId, Vector const &cloneLoc, Vector const &cloneRespawn, NetworkId const &cloneRespawnCell, NetworkId const &cloneId);
void setCitizen(int cityId, NetworkId const &citizenId, std::string const &citizenName, NetworkId const &allegiance, int permissions);
void setCitizenProfessionInfo(int cityId, NetworkId const &citizenId, std::string const &citizenProfessionSkillTemplate, int citizenLevel);
void addCitizenRank(int cityId, NetworkId const &citizenId, std::string const &rankName);
void removeCitizenRank(int cityId, NetworkId const &citizenId, std::string const &rankName);
bool hasCitizenRank(int cityId, NetworkId const &citizenId, std::string const &rankName);
void getCitizenRank(int cityId, NetworkId const &citizenId, stdvector<std::string>::fwd &ranks);
void setCitizenTitle(int cityId, NetworkId const &citizenId, std::string const &citizenTitle);
void setCityStructure(int cityId, NetworkId const &structureId, int structureType, bool structureValid);
bool cityExists(int cityId) const;
CityInfo const &getCityInfo(int cityId) const;
void getAllCityIds(stdvector<int>::fwd &results) const;
stdmap<int, CityInfo>::fwd const &getAllCityInfo() const;
int findCityByName(std::string const &name) const;
int findCityByCityHall(NetworkId const &cityHallId) const;
int getCityAtLocation(std::string const &planetName, int x, int z, int radius) const;
void getCitizenIds(int cityId, stdvector<NetworkId>::fwd &results) const;
stdmap<std::pair<int, NetworkId>, CitizenInfo>::fwd const &getAllCitizensInfo() const;
CitizenInfo const *getCitizenInfo(int cityId, NetworkId const &citizenId) const;
void getCityStructureIds(int cityId, stdvector<NetworkId>::fwd &results) const;
stdmap<std::pair<int, NetworkId>, CityStructureInfo>::fwd const & getAllCityStructuresInfo() const;
CityStructureInfo const *getCityStructureInfo(int cityId, NetworkId const &structureId) const;
stdvector<int>::fwd const & getCitizenOfCityId(NetworkId const &citizenId) const;
std::map<std::pair<std::string, int>, uint32> const & getGcwRegionDefenderCities() const;
std::map<std::string, std::pair<int, int> > const & getGcwRegionDefenderCitiesCount() const;
int getGcwRegionDefenderCitiesVersion() const;
void checkForDualCitizenship() const;
PgcRatingInfo const * getPgcRating(NetworkId const &chroniclerId) const;
void getPgcChroniclerId(std::string const &chroniclerName, std::vector<NetworkId> &chroniclerIds) const;
void adjustPgcRating(NetworkId const &chroniclerId, std::string const &chroniclerName, int adjustment);
void adjustPgcRatingData(NetworkId const &chroniclerId, std::string const &chroniclerName, int index, int adjustment);
void setPgcRatingData(NetworkId const &chroniclerId, std::string const &chroniclerName, int index, int value);
void verifyPgcChroniclerName(NetworkId const &chroniclerId, std::string const &chroniclerName);
private:
CityObject();
CityObject(CityObject const &rhs);
CityObject& operator=(CityObject const &rhs);
void addMembersToPackages();
int nextFreeCityId();
void getCitySpec(int cityId, std::string &result) const;
CitizenInfo const * getCitizenSpec(int cityId, NetworkId const &citizenId, std::string &result) const;
CityStructureInfo const * getCityStructureSpec(int cityId, NetworkId const &structureId, std::string &result) const;
void setCitySpec(int cityId, std::string const &newCitySpec);
bool findCitySpec(int cityId, std::string &citySpec) const;
void setCitizen(std::string const &oldCitizenSpec, std::string const &newCitizenSpec);
void addGcwRegionDefenderCity(std::string const & gcwRegion, int cityId, uint32 faction);
void removeGcwRegionDefenderCity(std::string const & gcwRegion, int cityId, uint32 faction);
void onCitizensInfoErase(std::pair<int, NetworkId> const & key, CitizenInfo const & value);
void onCitizensInfoInsert(std::pair<int, NetworkId> const & key, CitizenInfo const & value);
void onCitizensInfoSet(std::pair<int, NetworkId> const & key, CitizenInfo const & oldValue, CitizenInfo const & newValue);
private:
// BPM CityObject : UniverseObject // Begin persisted members
Archive::AutoDeltaSet<std::string> m_cities;
Archive::AutoDeltaSet<std::string> m_citizens;
Archive::AutoDeltaSet<std::string> m_structures;
// EPM
// parallel maps to persisted members m_cities, m_citizens, and m_structures that
// will provide access to the data because the data in the persisted members are strings
Archive::AutoDeltaMap<int, CityInfo> m_citiesInfo; // city id -> CityInfo
Archive::AutoDeltaMap<std::pair<int, NetworkId>, CitizenInfo, CityObject> m_citizensInfo; // (city id, citizen id) -> CitizenInfo
Archive::AutoDeltaMap<std::pair<int, NetworkId>, CityStructureInfo> m_structuresInfo; // (city id, structure id) -> CityStructureInfo
Archive::AutoDeltaMap<NetworkId, std::vector<int> > m_citizenToCityId; // citizen id -> city id (could be multiple for the bug where a character is a citizen of multiple cities)
Archive::AutoDeltaMap<NetworkId, PgcRatingInfo> m_pgcRatingInfo;
Archive::AutoDeltaSet<std::pair<std::string, NetworkId> > m_pgcRatingChroniclerId; // <lowercase chronicler first name, chronicler id>
Archive::AutoDeltaMap<std::pair<std::string, int>, uint32> m_gcwRegionDefenderCities;
Archive::AutoDeltaMap<std::string, std::pair<int, int> > m_gcwRegionDefenderCitiesCount;
Archive::AutoDeltaVariable<int> m_gcwRegionDefenderCitiesVersion;
int m_lowFreeCityId;
};
// ----------------------------------------------------------------------
inline std::map<std::pair<std::string, int>, uint32> const & CityObject::getGcwRegionDefenderCities() const
{
return m_gcwRegionDefenderCities.getMap();
}
// ----------------------------------------------------------------------
inline std::map<std::string, std::pair<int, int> > const & CityObject::getGcwRegionDefenderCitiesCount() const
{
return m_gcwRegionDefenderCitiesCount.getMap();
}
// ----------------------------------------------------------------------
inline int CityObject::getGcwRegionDefenderCitiesVersion() const
{
return m_gcwRegionDefenderCitiesVersion.get();
}
// ======================================================================
#endif
@@ -0,0 +1,158 @@
// ======================================================================
//
// ContainmentMessageManager.cpp
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/ContainmentMessageManager.h"
#include "serverGame/ConnectionServerConnection.h"
#include "serverGame/ContainerInterface.h"
#include "serverGame/DistributionListStack.h"
#include "serverGame/ServerObject.h"
#include "serverNetworkMessages/GameConnectionServerMessages.h"
#include "sharedNetworkMessages/UpdateContainmentMessage.h"
#include "sharedObject/ContainedByProperty.h"
#include "sharedObject/SlottedContainmentProperty.h"
#include <algorithm>
// ======================================================================
//
// Order of containment messages is preserved, and changes are sent for any objects that still exist.
// Containment states for each update are as of the time at which the message is added, to preserve causality.
//
// ======================================================================
namespace ContainmentMessageManagerNamespace
{
// ----------------------------------------------------------------------
class ContainmentMessageData
{
public:
ContainmentMessageData();
explicit ContainmentMessageData(ServerObject &object);
void update() const;
private:
Watcher<ServerObject> m_watcher;
NetworkId m_containedBy;
int m_currentArrangement;
};
// ----------------------------------------------------------------------
std::vector<ContainmentMessageData> s_containmentMessages;
std::map<NetworkId, std::set<Client *> > s_frameBaselines;
// ----------------------------------------------------------------------
std::set<Client *> const *getClientBaselinesThisFrame(NetworkId const &networkId);
// ----------------------------------------------------------------------
}
using namespace ContainmentMessageManagerNamespace;
// ======================================================================
void ContainmentMessageManager::addContainmentMessage(ServerObject &object)
{
s_containmentMessages.push_back(ContainmentMessageData(object));
}
// ----------------------------------------------------------------------
void ContainmentMessageManager::addFrameBaselines(NetworkId const &networkId, std::vector<Watcher<Client> > const &distributionList)
{
std::set<Client *>& baselines = s_frameBaselines[networkId];
for (std::vector<Watcher<Client> >::const_iterator i = distributionList.begin(); i != distributionList.end(); ++i)
IGNORE_RETURN(baselines.insert(*i));
}
// ----------------------------------------------------------------------
void ContainmentMessageManager::update()
{
for (std::vector<ContainmentMessageData>::iterator i = s_containmentMessages.begin(); i != s_containmentMessages.end(); ++i)
(*i).update();
s_containmentMessages.clear();
s_frameBaselines.clear();
}
// ----------------------------------------------------------------------
ContainmentMessageManagerNamespace::ContainmentMessageData::ContainmentMessageData() :
m_watcher(),
m_containedBy(NetworkId::cms_invalid),
m_currentArrangement(-1)
{
}
// ----------------------------------------------------------------------
ContainmentMessageManagerNamespace::ContainmentMessageData::ContainmentMessageData(ServerObject &object) :
m_watcher(&object),
m_containedBy(ContainerInterface::getContainedByProperty(object)->getContainedByNetworkId()),
m_currentArrangement(ContainerInterface::getSlottedContainmentProperty(object)->getCurrentArrangement())
{
}
// ----------------------------------------------------------------------
void ContainmentMessageManagerNamespace::ContainmentMessageData::update() const
{
static std::set<Client *> clientResultSet;
ServerObject * const obj = m_watcher.getPointer();
if (obj)
{
std::set<Client *> const &observers = obj->getObservers();
std::set<Client *> const * const baselines = getClientBaselinesThisFrame(obj->getNetworkId());
std::set<Client *> const *clients;
if (!baselines)
clients = &observers;
else
{
clientResultSet.clear();
std::insert_iterator<std::set<Client *> > insertIter(clientResultSet, clientResultSet.begin());
IGNORE_RETURN(std::set_difference(observers.begin(), observers.end(), baselines->begin(), baselines->end(), insertIter));
clients = &clientResultSet;
}
std::map<ConnectionServerConnection *, std::vector<NetworkId> > &tmpDistributionList = DistributionListStack::alloc();
for (std::set<Client *>::const_iterator i = clients->begin(); i != clients->end(); ++i)
tmpDistributionList[(*i)->getConnection()].push_back((*i)->getCharacterObjectId());
if (!tmpDistributionList.empty())
{
UpdateContainmentMessage const ucm(obj->getNetworkId(), m_containedBy, m_currentArrangement);
for (std::map<ConnectionServerConnection *, std::vector<NetworkId> >::const_iterator j = tmpDistributionList.begin(); j != tmpDistributionList.end(); ++j)
{
GameClientMessage const gcm((*j).second, true, ucm);
(*j).first->send(gcm, true);
}
}
DistributionListStack::release();
clientResultSet.clear();
}
}
// ----------------------------------------------------------------------
std::set<Client *> const *ContainmentMessageManagerNamespace::getClientBaselinesThisFrame(NetworkId const &networkId)
{
std::map<NetworkId, std::set<Client *> >::const_iterator i = s_frameBaselines.find(networkId);
if (i != s_frameBaselines.end())
return &((*i).second);
return 0;
}
// ======================================================================
@@ -0,0 +1,35 @@
// ======================================================================
//
// ContainmentMessageManager.h
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#ifndef _ContainmentMessageManager_H_
#define _ContainmentMessageManager_H_
// ======================================================================
#include "serverGame/Client.h"
// ======================================================================
class ContainmentMessageManager
{
public:
static void addContainmentMessage(ServerObject &object);
static void addFrameBaselines(NetworkId const &networkId, std::vector<Watcher<Client> > const &distributionList);
static void update();
private:
ContainmentMessageManager();
~ContainmentMessageManager();
ContainmentMessageManager(ContainmentMessageManager const &);
ContainmentMessageManager &operator=(ContainmentMessageManager const &);
};
// ======================================================================
#endif // _ContainmentMessageManager_H_
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,229 @@
// ======================================================================
//
// CreatureObject_Ships.cpp
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/CreatureObject.h"
#include "serverGame/CellObject.h"
#include "serverGame/ConfigServerGame.h"
#include "serverGame/ContainerInterface.h"
#include "serverGame/GameServer.h"
#include "serverGame/GroupObject.h"
#include "serverGame/ShipClientUpdateTracker.h"
#include "serverGame/ShipObject.h"
#include "sharedFoundation/ConstCharCrcLowerString.h"
#include "sharedGame/ShipSlotIdManager.h"
#include "sharedObject/CellProperty.h"
#include "sharedObject/ContainedByProperty.h"
#include "sharedObject/SlottedContainer.h"
#include "sharedObject/SlottedContainmentProperty.h"
// ======================================================================
/**
* Instruct this pilot to ride on the specified ship.
*
* @param mountObject the ShipObject that will be ridden by this
* instance.
*
* @return true if this pilot was able to mount the ship; false otherwise.
*/
bool CreatureObject::pilotShip(ServerObject &pilotSlotObject)
{
//-- Ensure ships are enabled.
if (!ConfigServerGame::getShipsEnabled())
{
return false;
}
//-- Ensure we (the pilot) are not already piloting a ship.
if (getPilotedShip())
{
DEBUG_FATAL(true, ("pilotShip(): pilot id=[%s] template=[%s] is already piloting a ship.", getNetworkId().getValueString().c_str(), getObjectTemplateName()));
return false;
}
//-- Ensure both the ship and the pilot are authoritative on this server.
// (They should be by design of how this function gets called.)
if (!isAuthoritative() || !pilotSlotObject.isAuthoritative())
{
DEBUG_WARNING(true, ("pilotShip(): pilot id=[%s] or ship id=[%s] was not authoritative on this server, mounting aborted.", getNetworkId().getValueString().c_str(), pilotSlotObject.getNetworkId().getValueString().c_str()));
return false;
}
ShipObject *shipObject = ShipObject::getContainingShipObject(&pilotSlotObject);
NOT_NULL(shipObject);
//-- Reject if the ship is not in the world cell
if (!shipObject->isInWorldCell())
{
DEBUG_WARNING(true, ("pilotShip(): ship id=[%s] is not in the world cell, mounting ship aborted.", shipObject->getNetworkId().getValueString().c_str()));
return false;
}
// If directly contained by a ship, we use the pilot slot, else we use the pob pilot slot
SlotId const pilotSlotId = pilotSlotObject.asShipObject() ? ShipSlotIdManager::getShipPilotSlotId() : ShipSlotIdManager::getPobShipPilotSlotId();
Container::ContainerErrorCode errorCode = Container::CEC_Success;
bool const transferSuccess = ContainerInterface::transferItemToSlottedContainer(pilotSlotObject, *this, pilotSlotId, NULL, errorCode);
DEBUG_FATAL(transferSuccess && (errorCode != Container::CEC_Success), ("pilotShip(): transferItemToSlottedContainer() returned success but container error code returned error %d.", static_cast<int>(errorCode)));
if (transferSuccess)
{
Client * const client = getClient();
if (client)
client->addControlledObject(*shipObject);
}
//-- Indicate transfer success.
return transferSuccess;
}
// ----------------------------------------------------------------------
bool CreatureObject::unpilotShip()
{
//-- Only do this on the authoritative pilot.
if (!isAuthoritative())
{
DEBUG_REPORT_LOG(true, ("CreatureObject::unpilotShip(): server id=[%d], ship id=[%s], skipping call because ship is not authoritative.",
static_cast<int>(GameServer::getInstance().getProcessId()),
getNetworkId().getValueString().c_str()));
return false;
}
//-- Ensure ships are enabled.
if (!ConfigServerGame::getShipsEnabled())
return false;
bool unpilotedShip = false;
ShipObject* ship = getPilotedShip();
if (!ship)
return false;
ServerObject * const containingObject = NON_NULL(safe_cast<ServerObject *>(ContainerInterface::getContainedByObject(*this)));
// If directly contained by a ship, we use the pilot slot, else we use the pob pilot slot
SlotId const pilotSlotId = containingObject->asShipObject() ? ShipSlotIdManager::getShipPilotSlotId() : ShipSlotIdManager::getPobShipPilotSlotId();
// If this creature is piloting the ship, he is in the pilot slot of either the ship or an object contained by a cell of the ship.
SlottedContainer * const slottedContainer = ContainerInterface::getSlottedContainer(*containingObject);
if (slottedContainer)
{
//-- Check for a pilot.
Container::ContainerErrorCode errorCode = Container::CEC_Success;
CachedNetworkId pilotId = slottedContainer->getObjectInSlot(pilotSlotId, errorCode);
if (errorCode == Container::CEC_Success)
{
ServerObject * const pilot = safe_cast<ServerObject*>(pilotId.getObject());
FATAL(pilot != this, ("Somehow told to unpilot a ship when we are not the pilot of the ship!"));
// Transfer pilot to location of the object it was contained by, which may or may not have been the ship, but it something with a pilot slot.
CellObject * const destCell = dynamic_cast<CellObject *>(containingObject->getAttachedTo());
if (destCell)
{
Transform tr(containingObject->getTransform_o2p());
// push them back a meter as well if they are unpiloting a pob ship
if (!containingObject->asShipObject())
tr.move_l(Vector(0.f, 0.f, -1.f));
IGNORE_RETURN(ContainerInterface::transferItemToCell(*destCell, *this, tr, 0, errorCode));
}
else
IGNORE_RETURN(ContainerInterface::transferItemToWorld(*this, containingObject->getTransform_o2w(), 0, errorCode));
if (errorCode == Container::CEC_Success)
unpilotedShip = true;
}
}
Client * const client = getClient();
if (client)
{
client->removeControlledObject(*ship);
// make sure the client can start receiving updates for the ship
ShipClientUpdateTracker::queueForUpdate(*client, *ship);
}
return unpilotedShip;
}
//----------------------------------------------------------------------
ShipObject const *CreatureObject::getPilotedShip() const
{
return const_cast<CreatureObject*>(this)->getPilotedShip();
}
//----------------------------------------------------------------------
ShipObject *CreatureObject::getPilotedShip()
{
//-- Ensure ships are enabled.
if (!ConfigServerGame::getShipsEnabled())
return 0;
// If we are occupying a "pilot" slot of our immediate container, then we are indirectly contained by a ship which we are piloting
SlottedContainmentProperty const *slottedContainmentProperty = ContainerInterface::getSlottedContainmentProperty(*this);
if (slottedContainmentProperty)
{
int currentArrangement = slottedContainmentProperty->getCurrentArrangement();
if (currentArrangement != -1)
{
SlottedContainmentProperty::SlotArrangement const &slotArrangement = slottedContainmentProperty->getSlotArrangement(currentArrangement);
for (SlottedContainmentProperty::SlotArrangement::const_iterator i = slotArrangement.begin(); i != slotArrangement.end(); ++i)
if ((*i) == ShipSlotIdManager::getShipPilotSlotId() || (*i) == ShipSlotIdManager::getPobShipPilotSlotId())
return ShipObject::getContainingShipObject(this);
}
}
return 0;
}
//----------------------------------------------------------------------
void CreatureObject::getAllShipsInDatapad(std::vector<NetworkId> & result) const
{
ServerObject const * const datapad = getDatapad();
if(datapad)
{
Container const * const datapadContainer = ContainerInterface::getContainer(*datapad);
if(datapadContainer)
{
//look at each item in the datapad for the ship control devices
for(ContainerConstIterator iter = datapadContainer->begin(); iter != datapadContainer->end(); ++iter)
{
Object const * const itemO = (*iter).getObject();
ServerObject const * const itemSO = itemO ? itemO->asServerObject() : NULL;
if(itemSO && (itemSO->getGameObjectType() == SharedObjectTemplate::GOT_data_ship_control_device))
{
Container const * const itemContainer = ContainerInterface::getContainer(*itemSO);
{
if(!itemContainer)
continue;
//for each ship control device, see if the item contains a shipobject
for(ContainerConstIterator iter2 = itemContainer->begin(); iter2 != itemContainer->end(); ++iter2)
{
Object const * const o = (*iter2).getObject();
ServerObject const * const so = o ? o->asServerObject() : NULL;
ShipObject const * const ship = so ? so->asShipObject() : NULL;
if(ship)
{
result.push_back(ship->getNetworkId());
}
}
}
}
}
}
}
}
// ======================================================================
@@ -0,0 +1,103 @@
// ======================================================================
//
// DestroyMessageManager.cpp
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/DestroyMessageManager.h"
#include "serverGame/Client.h"
#include "serverGame/ConnectionServerConnection.h"
#include "serverNetworkMessages/GameConnectionServerMessages.h"
#include "sharedFoundation/NetworkIdArchive.h"
#include "sharedNetworkMessages/SceneChannelMessages.h"
#ifdef _DEBUG
#include "serverGame/ServerObject.h"
#include "sharedObject/NetworkIdManager.h"
#endif
// ======================================================================
//
// Destroy messages are in arbitrary order.
//
// ======================================================================
namespace DestroyMessageManagerNamespace
{
std::map<NetworkId, std::pair<std::set<Watcher<Client> >, bool> > s_destroyMap;
}
using namespace DestroyMessageManagerNamespace;
// ======================================================================
void DestroyMessageManager::add(Client *client, NetworkId const &destroyId, bool const hyperspace)
{
s_destroyMap[destroyId].first.insert(Watcher<Client>(client));
s_destroyMap[destroyId].second = hyperspace;
}
// ----------------------------------------------------------------------
bool DestroyMessageManager::remove(Client const *client, NetworkId const &destroyId)
{
std::map<NetworkId, std::pair<std::set<Watcher<Client> >, bool> >::iterator i = s_destroyMap.find(destroyId);
if (i != s_destroyMap.end())
{
std::set<Watcher<Client> > &clients = (*i).second.first;
std::set<Watcher<Client> >::iterator j = std::find(clients.begin(), clients.end(), client);
if (j != clients.end())
{
if (clients.size() == 1)
s_destroyMap.erase(i);
else
clients.erase(j);
return true;
}
}
return false;
}
// ----------------------------------------------------------------------
void DestroyMessageManager::update()
{
for (std::map<NetworkId, std::pair<std::set<Watcher<Client> >, bool> >::const_iterator i = s_destroyMap.begin(); i != s_destroyMap.end(); ++i)
{
#ifdef _DEBUG
Object const * const o = NetworkIdManager::getObjectById((*i).first);
DEBUG_FATAL(o && o->asServerObject() && o->asServerObject()->getCacheVersion() > 0, ("Tried to destroy cached object %s", (*i).first.getValueString().c_str()));
#endif
std::set<Watcher<Client> > const &clientSet = (*i).second.first;
bool const hyperspace = (*i).second.second;
typedef std::map<ConnectionServerConnection *, std::vector<NetworkId> > DistributionList;
DistributionList distributionList;
for (std::set<Watcher<Client> >::const_iterator j = clientSet.begin(); j != clientSet.end(); ++j)
{
Client * const client = (*j).getPointer();
if (client)
distributionList[client->getConnection()].push_back(client->getCharacterObjectId());
}
if (!distributionList.empty())
{
SceneDestroyObject const message((*i).first, hyperspace);
for (DistributionList::const_iterator k = distributionList.begin(); k != distributionList.end(); ++k)
{
GameClientMessage const gcm((*k).second, true, message);
(*k).first->send(gcm, true);
}
}
}
s_destroyMap.clear();
}
// ======================================================================
@@ -0,0 +1,36 @@
// ======================================================================
//
// DestroyMessageManager.h
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#ifndef _DestroyMessageManager_H_
#define _DestroyMessageManager_H_
// ======================================================================
class Client;
class NetworkId;
// ======================================================================
class DestroyMessageManager
{
public:
static void add(Client *client, NetworkId const &destroyId, bool hyperspace);
static bool remove(Client const *client, NetworkId const &destroyId);
static void update();
private:
DestroyMessageManager();
~DestroyMessageManager();
DestroyMessageManager(DestroyMessageManager const &);
DestroyMessageManager &operator=(DestroyMessageManager const &);
};
// ======================================================================
#endif // _DestroyMessageManager_H_
@@ -0,0 +1,41 @@
// ======================================================================
//
// DistributionListStack.cpp
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/DistributionListStack.h"
#include <map>
#include <vector>
// ======================================================================
namespace DistributionListStackNamespace
{
const unsigned int cms_maxDistributionLists = 16;
std::map<ConnectionServerConnection *, std::vector<NetworkId> > s_distributionLists[cms_maxDistributionLists];
unsigned int s_distributionListCount;
}
using namespace DistributionListStackNamespace;
// ======================================================================
std::map<ConnectionServerConnection *, std::vector<NetworkId> > &DistributionListStack::alloc()
{
FATAL(s_distributionListCount == cms_maxDistributionLists, ("DistributionListStack::alloc too many entries on stack"));
return s_distributionLists[s_distributionListCount++];
}
// ----------------------------------------------------------------------
void DistributionListStack::release()
{
FATAL(s_distributionListCount == 0, ("DistributionListStack::release with empty stack"));
s_distributionLists[--s_distributionListCount].clear();
}
// ======================================================================
@@ -0,0 +1,37 @@
// ======================================================================
//
// DistributionListStack.h
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#ifndef _DistributionListStack_H_
#define _DistributionListStack_H_
// ======================================================================
#include "sharedFoundation/NetworkId.h"
// ======================================================================
class ConnectionServerConnection;
// ======================================================================
class DistributionListStack
{
public:
static stdmap<ConnectionServerConnection *, stdvector<NetworkId>::fwd>::fwd &alloc();
static void release();
private:
DistributionListStack();
DistributionListStack(DistributionListStack const &);
DistributionListStack &operator=(DistributionListStack const &);
};
// ======================================================================
#endif // _DistributionListStack_H_
@@ -0,0 +1,566 @@
//========================================================================
//
// DraftSchematicObject.cpp
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/DraftSchematicObject.h"
#include "UnicodeUtils.h"
#include "serverGame/ManufactureSchematicObject.h"
#include "serverGame/ObjectIdManager.h"
#include "serverGame/ServerController.h"
#include "serverGame/ServerManufactureSchematicObjectTemplate.h"
#include "serverScript/GameScriptObject.h"
#include "serverScript/ScriptParameters.h"
#include "sharedFile/TreeFile.h"
#include "sharedFoundation/ConstCharCrcLowerString.h"
#include "sharedFoundation/ConstCharCrcString.h"
#include "sharedFoundation/Crc.h"
#include "sharedGame/SharedObjectTemplate.h"
#include "sharedNetworkMessages/MessageQueueResourceWeights.h"
#include "sharedObject/NetworkController.h"
#include "sharedObject/ObjectTemplateList.h"
// ======================================================================
// local constants
static const int MAX_ATTRIBUTES = 32;
static const std::string REQUEST_RESOURCE_WEIGHTS_SCRIPT_METHOD("OnRequestResourceWeights");
// ======================================================================
// static members
DraftSchematicObject::SchematicMap * DraftSchematicObject::m_schematics = NULL;
const SharedObjectTemplate * DraftSchematicObject::m_defaultSharedTemplate = NULL;
// ======================================================================
/**
* Class constructor.
*
* @param newTemplate template to create the schematic from.
*/
DraftSchematicObject::DraftSchematicObject(
const ServerDraftSchematicObjectTemplate* newTemplate) :
IntangibleObject(newTemplate),
m_slots(),
m_attributes(),
m_experimentalAttributes(),
m_combinedCrc(newTemplate->getCrcName().getCrc(), getSharedTemplate()->getCrcName().getCrc())
{
int i;
ServerDraftSchematicObjectTemplate::IngredientSlot slot;
// put the slots in the name lookup map
int count = newTemplate->getSlotsCount();
for (i = 0; i < count; ++i)
{
newTemplate->getSlots(slot, i);
m_slots.insert(std::make_pair(slot.name, i));
}
// get the experimental attributes from the attributes, and create a map
// between them
int minValue = 0, maxValue = 0;
count = getAttribsCount();
for (i = 0; i < count; ++i)
{
const SharedDraftSchematicObjectTemplate::SchematicAttribute & attrib =
getAttrib(i);
m_attributes[attrib.name] = i;
if (!attrib.experiment.getTable().empty() && !attrib.experiment.getText().empty())
{
getAttribMinMax(i, minValue, maxValue);
if (minValue != maxValue)
m_experimentalAttributes[attrib.experiment].push_back(attrib.name);
}
}
} // DraftSchematicObject::DraftSchematicObject
//-----------------------------------------------------------------------
/**
* Class destructor.
*/
DraftSchematicObject::~DraftSchematicObject()
{
} // DraftSchematicObject::~DraftSchematicObject
//-----------------------------------------------------------------------
/**
* Returns a shared template if none was given for this object.
*
* @return the shared template
*/
const SharedObjectTemplate * DraftSchematicObject::getDefaultSharedTemplate(void) const
{
static const ConstCharCrcLowerString templateName("object/draft_schematic/base/shared_draft_schematic_default.iff");
if (m_defaultSharedTemplate == NULL)
{
m_defaultSharedTemplate = safe_cast<const SharedObjectTemplate *>(
ObjectTemplateList::fetch(templateName));
WARNING_STRICT_FATAL(m_defaultSharedTemplate == NULL, ("Cannot create "
"default shared object template %s", templateName.getString()));
if (m_defaultSharedTemplate != NULL)
ExitChain::add (removeDefaultTemplate, "DraftSchematicObject::removeDefaultTemplate");
}
return m_defaultSharedTemplate;
} // DraftSchematicObject::getDefaultSharedTemplate
//-----------------------------------------------------------------------
/**
* Cleans up the default shared template.
*/
void DraftSchematicObject::removeDefaultTemplate(void)
{
if (m_defaultSharedTemplate != NULL)
{
m_defaultSharedTemplate->releaseReference();
m_defaultSharedTemplate = NULL;
}
} // DraftSchematicObject::removeDefaultTemplate
//-----------------------------------------------------------------------
/**
* Requests info about resource weights for a given draft schematic.
*
* @param requester the player making the request
* @param draftSchematicName the schematic the player wants to know about
*/
void DraftSchematicObject::requestResourceWeights(ServerObject & requester, uint32 draftSchematicCrc)
{
if (requester.getClient() == NULL)
{
WARNING (true, ("DraftSchematicObject::requestResourceWeights invalid client for [%s]", requester.getNetworkId ().getValueString ().c_str ()));
return;
}
const DraftSchematicObject * const schematic = getSchematic(draftSchematicCrc);
if (schematic == NULL)
{
WARNING (true, ("DraftSchematicObject::requestResourceWeights invalid schematic [%lu] for [%s]", draftSchematicCrc, requester.getNetworkId ().getValueString ().c_str ()));
return;
}
const ServerDraftSchematicObjectTemplate * const schematicTemplate = safe_cast<const ServerDraftSchematicObjectTemplate *>(schematic->getObjectTemplate());
if (schematicTemplate == NULL)
{
WARNING (true, ("DraftSchematicObject::requestResourceWeights invalid schematic template [%lu] for [%s]", draftSchematicCrc, requester.getNetworkId ().getValueString ().c_str ()));
return;
}
std::vector<const char *> desiredAttribs;
{
for (NameToIndexMap::const_iterator i = schematic->m_attributes.begin(); i != schematic->m_attributes.end(); ++i)
desiredAttribs.push_back((*i).first.getText().c_str());
}
std::vector<const char *> attributes(MAX_ATTRIBUTES * 2, static_cast<const char *>(NULL));
std::vector<int> slots(MAX_ATTRIBUTES * 2, 0);
std::vector<int> counts(MAX_ATTRIBUTES * 2, 0);
std::vector<int> weights(MAX_ATTRIBUTES * 2 * Crafting::RA_numResourceAttributes * 2, 0);
ScriptParams params;
params.addParam(requester.getNetworkId());
params.addParam(desiredAttribs);
params.addParam(attributes);
params.addParam(slots);
params.addParam(counts);
params.addParam(weights);
// call script function
GameScriptObject::runOneScript(schematicTemplate->getManufactureScripts(0), REQUEST_RESOURCE_WEIGHTS_SCRIPT_METHOD, "Os[s*[i*[i*[i*[", params);
const std::vector<const char *> & newAttributes = params.getStringArrayParam(2);
const std::vector<int> & newSlots = params.getIntArrayParam(3);
const std::vector<int> & newCounts = params.getIntArrayParam(4);
const std::vector<int> & newWeights = params.getIntArrayParam(5);
std::vector<int>::const_iterator slotIter(newSlots.begin());
std::vector<int>::const_iterator countIter(newCounts.begin());
std::vector<int>::const_iterator weightIter(newWeights.begin());
MessageQueueResourceWeights * const message = new MessageQueueResourceWeights(schematic->getCombinedCrc());
// find out how many attributes were returned
int attribCount = 0;
{
for (std::vector<const char *>::const_iterator i(newAttributes.begin());
i != newAttributes.end(); ++i, ++attribCount)
{
if (*i == NULL)
break;
}
}
attribCount /= 2;
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < attribCount; ++j)
{
const StringId sid("crafting", newAttributes[j + i * attribCount]);;
const int attrib = schematic->getAttribIndex(sid);
if (attrib == -1)
{
// skip over the data for that attrib
slotIter++;
const int weightCount = *countIter++;
weightIter += weightCount * 2;
continue;
}
const int slot = *slotIter++;
const int weightCount = *countIter++;
for (int k = 0; k < weightCount; ++k)
{
const int resource = *weightIter++;
const int weight = *weightIter++;
if (i == 0)
{
message->addAssemblyWeight(attrib, slot, resource, weight);
}
else
{
message->addResourceMaxWeight(attrib, slot, resource, weight);
}
}
}
}
(safe_cast<ServerController *>(requester.getController()))->appendMessage(
static_cast<int>(CM_resourceWeights), 0.0f, message,
GameControllerMessageFlags::SEND |
GameControllerMessageFlags::RELIABLE |
GameControllerMessageFlags::DEST_AUTH_CLIENT);
} // DraftSchematicObject::requestResourceWeights
//-----------------------------------------------------------------------
/**
* Creates a manufacture schematic based on this schematic.
*
* @param creator the player creating the schematic
*
* @return the manufacture schematic
*/
ManufactureSchematicObject * DraftSchematicObject::createManufactureSchematic(
const CachedNetworkId & creator) const
{
Object * object = ServerManufactureSchematicObjectTemplate::createObject(
"object/manufacture_schematic/generic_schematic.iff", *this);
if (object == NULL)
return NULL;
ManufactureSchematicObject * schematic = safe_cast<ManufactureSchematicObject *>(object);
schematic->init(*this, creator);
schematic->setNetworkId(ObjectIdManager::getInstance().getNewObjectId());
return schematic;
} // DraftSchematicObject::createManufactureSchematic
//-----------------------------------------------------------------------
/**
* Gets a draft scrematic slot by name.
*
* @param slot slot info to be filled
* @param name name of the slot to get
*
* @return true on success, false if the slot wasn't found
*/
bool DraftSchematicObject::getSlot(
ServerDraftSchematicObjectTemplate::IngredientSlot & slot, int index) const
{
if (index < 0 || index >= static_cast<int>((safe_cast<
const ServerDraftSchematicObjectTemplate*>(
getObjectTemplate()))->getSlotsCount()))
{
return false;
}
slot.options.clear();
(safe_cast<const ServerDraftSchematicObjectTemplate*>(getObjectTemplate()))->getSlots(slot, index);
return true;
}
//-----------------------------------------------------------------------
/**
* Gets a draft scrematic slot by name.
*
* @param slot slot info to be filled
* @param name name of the slot to get
*
* @return true on success, false if the slot wasn't found
*/
bool DraftSchematicObject::getSlot(
ServerDraftSchematicObjectTemplate::IngredientSlot & slot, const StringId & name) const
{
NameToIndexMap::const_iterator iter = m_slots.find(name);
if (iter != m_slots.end())
return getSlot(slot, (*iter).second);
return false;
} // DraftSchematicObject::getSlot(const StringId &)
//-----------------------------------------------------------------------
/**
* Gets the min and max values for an attribute of the schematic.
*
* @param index index of the object attribute
* @param minValue value that will be filled in with the min attribute value
* @param maxValue value that will be filled in with the max attribute value
*
* @return true on success, false if the name is not a valid attribute
*/
bool DraftSchematicObject::getAttribMinMax(int index, int & minValue,
int & maxValue) const
{
const SharedDraftSchematicObjectTemplate::SchematicAttribute & minAttrib =
getAttribMin(index);
minValue = minAttrib.value;
const SharedDraftSchematicObjectTemplate::SchematicAttribute & maxAttrib =
getAttribMax(index);
minValue = minAttrib.value;
maxValue = maxAttrib.value;
return true;
} // DraftSchematicObject::getAttribMinMax(int)
//-----------------------------------------------------------------------
/**
* Gets the min and max values for an attribute of the schematic.
*
* @param name the attribute name
* @param minValue value that will be filled in with the min attribute value
* @param maxValue value that will be filled in with the max attribute value
*
* @return true on success, false if the name is not a valid attribute
*/
bool DraftSchematicObject::getAttribMinMax(const StringId & name, int & minValue,
int & maxValue) const
{
NameToIndexMap::const_iterator iter = m_attributes.find(name);
if (iter == m_slots.end())
return false;
int index = (*iter).second;
return getAttribMinMax(index, minValue, maxValue);
} // DraftSchematicObject::getAttribMinMax(const StringId &)
//-----------------------------------------------------------------------
/**
* Returns the name of a experimental attribute associated with an object attribute.
*
* @param index index of the object attribute
*
* @return the experimental attribute name
*/
const StringId DraftSchematicObject::getExperimentalAttributeFromAttribute(
int index) const
{
static const StringId NO_EXPERIMENTATION;
const SharedDraftSchematicObjectTemplate::SchematicAttribute & attrib =
getAttrib(index);
if (attrib.experiment == NO_EXPERIMENTATION)
return NO_EXPERIMENTATION;
// make sure we can really experiment with the attribute
int minValue, maxValue;
if (!getAttribMinMax(index, minValue, maxValue))
return NO_EXPERIMENTATION;
if (minValue == maxValue)
{
WARNING(true, ("Draft schematic %s has attribute %s with experimental "
"attribute %s even though the attribute min/max values are the "
"same! Not allowing experimentation.", getObjectTemplateName(),
attrib.name.getCanonicalRepresentation().c_str(),
attrib.experiment.getCanonicalRepresentation().c_str()));
return NO_EXPERIMENTATION;
}
return attrib.experiment;
} // DraftSchematicObject::getExperimentalAttributeFromAttribute
//-----------------------------------------------------------------------
/**
* Returns the name of a experimental attribute associated with an object attribute.
*
* @param attribName the object attribute name
*
* @return the experimental attribute name
*/
const StringId DraftSchematicObject::getExperimentalAttributeFromAttribute(
const StringId & attribName) const
{
static const StringId NO_EXPERIMENTATION;
const SharedDraftSchematicObjectTemplate::SchematicAttribute & attrib =
getAttrib(attribName);
if (attrib.experiment == NO_EXPERIMENTATION)
return NO_EXPERIMENTATION;
// make sure we can really experiment with the attribute
int minValue, maxValue;
if (!getAttribMinMax(attribName, minValue, maxValue))
return NO_EXPERIMENTATION;
if (minValue == maxValue)
{
WARNING(true, ("Draft schematic %s has attribute %s with experimental "
"attribute %s even though the attribute min/max values are the "
"same! Not allowing experimentation.", getObjectTemplateName(),
attrib.name.getCanonicalRepresentation().c_str(),
attrib.experiment.getCanonicalRepresentation().c_str()));
return NO_EXPERIMENTATION;
}
return attrib.experiment;
} // DraftSchematicObject::getExperimentalAttributeFromAttribute
//-----------------------------------------------------------------------
/**
* Returns the names of object attributes associated with an experimental attribute.
*
* @param attribName the experimental attribute name
*
* @return the object attribute name list
*/
const std::vector<StringId> & DraftSchematicObject::getFromAttributeFromExperimentalAttribute(
const StringId & experimentAttribName) const
{
return (*m_experimentalAttributes.find(experimentAttribName)).second;
} // DraftSchematicObject::getFromAttributeFromExperimentalAttribute
// ======================================================================
// factory methods
/**
* Returns a draft schematic with a given name. If the schematic isn't loaded,
* loads it.
*
* @param name name of the schematic to load
*
* @return the draft schematic
*/
const DraftSchematicObject * DraftSchematicObject::getSchematic(
const std::string & name)
{
NOT_NULL(m_schematics);
return getSchematic(Crc::calculate(name.c_str()));
} // DraftSchematicObject::getSchematic(const std::string &)
//-----------------------------------------------------------------------
/**
* Returns a draft schematic with a given name. If the schematic isn't loaded,
* loads it.
*
* @param crc crc of name of the schematic to load
*
* @return the draft schematic
*/
const DraftSchematicObject * DraftSchematicObject::getSchematic(uint32 crc)
{
NOT_NULL(m_schematics);
if (m_schematics == NULL || crc == 0)
return NULL;
// see if the schematic is already loaded
SchematicMap::iterator result = m_schematics->find(crc);
if (result != m_schematics->end())
return (*result).second;
// get the template name from the crc
const ConstCharCrcString & name = ObjectTemplateList::lookUp(crc);
if (name.isEmpty())
{
WARNING(true, ("Unable to find template name for crc %u", crc));
return NULL;
}
// create a new schematic
if (!TreeFile::exists(name.getString()))
{
WARNING(true, ("Draft schematic template %s file not found", name.getString()));
return NULL;
}
const ObjectTemplate * objTemplate = ObjectTemplateList::fetch(name);
if (objTemplate == NULL)
{
WARNING(true, ("Can't create object template %s", name.getString()));
return NULL;
}
const ServerDraftSchematicObjectTemplate * schematicTemplate =
dynamic_cast<const ServerDraftSchematicObjectTemplate *>(objTemplate);
if (schematicTemplate == NULL)
{
WARNING(true, ("Template %s is not a draft schematic", name.getString()));
objTemplate->releaseReference();
return NULL;
}
const DraftSchematicObject * schematic = new DraftSchematicObject(schematicTemplate);
objTemplate->releaseReference();
m_schematics->insert(std::make_pair(crc, schematic));
return schematic;
} // DraftSchematicObject::getSchematic(uint32)
//-----------------------------------------------------------------------
/**
* Sets up the draft schematic factory.
*/
void DraftSchematicObject::install()
{
if (m_schematics == NULL)
m_schematics = new SchematicMap();
} // DraftSchematicObject::install
//-----------------------------------------------------------------------
/**
* Cleans up the draft schematic factory
*/
void DraftSchematicObject::remove()
{
if (m_schematics != NULL)
{
SchematicMap::iterator iter;
for (iter = m_schematics->begin(); iter != m_schematics->end(); ++iter)
{
delete (*iter).second;
(*iter).second = NULL;
}
delete m_schematics;
m_schematics = NULL;
}
} // DraftSchematicObject::remove
// ----------------------------------------------------------------------
void DraftSchematicObject::getAttributes(stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const
{
IntangibleObject::getAttributes(data);
}
// ======================================================================
@@ -0,0 +1,272 @@
//========================================================================
//
// DraftSchematicObject.h
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#ifndef INCLUDED_DraftSchematicObject_H
#define INCLUDED_DraftSchematicObject_H
#include "serverGame/IntangibleObject.h"
#include "serverGame/ServerDraftSchematicObjectTemplate.h"
#include "sharedGame/CraftingDataArchive.h"
#include "sharedGame/SharedDraftSchematicObjectTemplate.h"
class ManufactureSchematicObject;
/**
* A DraftSchematicObject is used to create designs for new objects.
*/
class DraftSchematicObject : public IntangibleObject
{
public:
// factory methods
static const DraftSchematicObject * getSchematic(const std::string & name);
static const DraftSchematicObject * getSchematic(uint32 crc);
static void install();
static void remove();
public:
virtual ~DraftSchematicObject();
static void removeDefaultTemplate(void);
static void requestResourceWeights(ServerObject & requester, uint32 draftSchematicCrc);
const std::pair<uint32, uint32> & getCombinedCrc() const;
ServerIntangibleObjectTemplate::CraftingType getCategory(void) const;
const ServerObjectTemplate * getCraftedObjectTemplate() const;
const ServerFactoryObjectTemplate * getCrateObjectTemplate() const;
bool getSlot(ServerDraftSchematicObjectTemplate::IngredientSlot & slot, const StringId & name) const;
bool getSlot(ServerDraftSchematicObjectTemplate::IngredientSlot & slot, int index) const;
int getSlotsCount(void) const;
int getAttribIndex(const StringId & name) const;
const SharedDraftSchematicObjectTemplate::SchematicAttribute & getAttrib(int index) const;
const SharedDraftSchematicObjectTemplate::SchematicAttribute & getAttrib(const StringId & name) const;
const SharedDraftSchematicObjectTemplate::SchematicAttribute & getAttribMin(int index) const;
const SharedDraftSchematicObjectTemplate::SchematicAttribute & getAttribMax(int index) const;
bool getAttribMinMax(const StringId & name, int & minValue, int & maxValue) const;
bool getAttribMinMax(int index, int & minValue, int & maxValue) const;
int getAttribsCount(void) const;
const StringId getExperimentalAttribute(int index) const;
size_t getExperimentalAttributesCount(void) const;
const std::string & getSkillCommands(int index) const;
int getSkillCommandsCount(void) const;
int getItemsPerContainer(void) const;
float getManufactureTime(void) const;
float getPrototypeTime(void) const;
bool mustDestroyIngredients(void) const;
virtual void getAttributes(stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const;
const StringId getExperimentalAttributeFromAttribute(int index) const;
const StringId getExperimentalAttributeFromAttribute(const StringId & attribName) const;
const std::vector<StringId> & getFromAttributeFromExperimentalAttribute(const StringId & experimentAttribName) const;
ManufactureSchematicObject * createManufactureSchematic(const CachedNetworkId & creator) const;
protected:
virtual const SharedObjectTemplate * getDefaultSharedTemplate(void) const;
// if in debug mode, make constructor public for datalint, else make it private
#ifdef _DEBUG
public:
explicit DraftSchematicObject(const ServerDraftSchematicObjectTemplate* newTemplate);
#else
private:
explicit DraftSchematicObject(const ServerDraftSchematicObjectTemplate* newTemplate);
#endif
private:
DraftSchematicObject();
DraftSchematicObject(const DraftSchematicObject& rhs);
DraftSchematicObject& operator=(const DraftSchematicObject& rhs);
private:
typedef std::map<StringId, int> NameToIndexMap;
typedef std::map<StringId, std::vector<StringId> > ExpAttribsMap;
NameToIndexMap m_slots; // for quick slot lookup by name
NameToIndexMap m_attributes; // for quick attribute lookup by name
ExpAttribsMap m_experimentalAttributes; // maps experimental attribs to attribs
const std::pair<uint32, uint32> m_combinedCrc; // server and shared template crcs
private:
static const SharedObjectTemplate * m_defaultSharedTemplate; // template to use if no shared template is given
// schematic factory fields
typedef std::map<uint32, const DraftSchematicObject *> SchematicMap;
// since draft schematics don't have valid NetworkIds, we keep track of them
// by their template name
static SchematicMap *m_schematics;
};
//========================================================================
inline ServerIntangibleObjectTemplate::CraftingType DraftSchematicObject::getCategory() const
{
return (safe_cast<const ServerDraftSchematicObjectTemplate *>(getObjectTemplate()))->getCategory();
}
//------------------------------------------------------------------------------
inline const ServerObjectTemplate * DraftSchematicObject::getCraftedObjectTemplate() const
{
return (safe_cast<const ServerDraftSchematicObjectTemplate*>(getObjectTemplate()))->getCraftedObjectTemplate();
}
//------------------------------------------------------------------------------
inline const ServerFactoryObjectTemplate * DraftSchematicObject::getCrateObjectTemplate() const
{
return (safe_cast<const ServerDraftSchematicObjectTemplate*>(getObjectTemplate()))->getCrateObjectTemplate();
}
//------------------------------------------------------------------------------
inline const std::pair<uint32, uint32> & DraftSchematicObject::getCombinedCrc() const
{
return m_combinedCrc;
}
//------------------------------------------------------------------------------
inline int DraftSchematicObject::getSlotsCount(void) const
{
return (safe_cast<const ServerDraftSchematicObjectTemplate*>(getObjectTemplate()))->getSlotsCount();
}
//------------------------------------------------------------------------------
inline int DraftSchematicObject::getAttribIndex(const StringId & name) const
{
NameToIndexMap::const_iterator iter = m_attributes.find(name);
if (iter == m_attributes.end())
return -1;
return (*iter).second;
}
//------------------------------------------------------------------------------
inline const SharedDraftSchematicObjectTemplate::SchematicAttribute &
DraftSchematicObject::getAttrib(int index) const
{
static SharedDraftSchematicObjectTemplate::SchematicAttribute slot;
(safe_cast<const SharedDraftSchematicObjectTemplate*>(getSharedTemplate()))->getAttributes(slot, index);
return slot;
}
//------------------------------------------------------------------------------
inline const SharedDraftSchematicObjectTemplate::SchematicAttribute &
DraftSchematicObject::getAttrib(const StringId & name) const
{
static SharedDraftSchematicObjectTemplate::SchematicAttribute slot;
NameToIndexMap::const_iterator iter = m_attributes.find(name);
if (iter != m_attributes.end())
return getAttrib((*iter).second);
return slot;
}
//------------------------------------------------------------------------------
inline const SharedDraftSchematicObjectTemplate::SchematicAttribute &
DraftSchematicObject::getAttribMin(int index) const
{
static SharedDraftSchematicObjectTemplate::SchematicAttribute slot;
(safe_cast<const SharedDraftSchematicObjectTemplate*>(getSharedTemplate()))->getAttributesMin(slot, index);
return slot;
}
//------------------------------------------------------------------------------
inline const SharedDraftSchematicObjectTemplate::SchematicAttribute &
DraftSchematicObject::getAttribMax(int index) const
{
static SharedDraftSchematicObjectTemplate::SchematicAttribute slot;
(safe_cast<const SharedDraftSchematicObjectTemplate*>(getSharedTemplate()))->getAttributesMax(slot, index);
return slot;
}
//------------------------------------------------------------------------------
inline int DraftSchematicObject::getAttribsCount(void) const
{
return (safe_cast<const SharedDraftSchematicObjectTemplate*>(getSharedTemplate()))->getAttributesCount();
}
//------------------------------------------------------------------------------
inline const StringId DraftSchematicObject::getExperimentalAttribute(int index) const
{
ExpAttribsMap::const_iterator iter = m_experimentalAttributes.begin();
for (int i = 0; i < index; ++i, ++iter);
return (*iter).first;
}
//------------------------------------------------------------------------------
inline size_t DraftSchematicObject::getExperimentalAttributesCount(void) const
{
return m_experimentalAttributes.size();
}
//------------------------------------------------------------------------------
inline const std::string & DraftSchematicObject::getSkillCommands(int index) const
{
return (safe_cast<const ServerDraftSchematicObjectTemplate*>(getObjectTemplate()))->getSkillCommands(index);
}
//------------------------------------------------------------------------------
inline int DraftSchematicObject::getSkillCommandsCount() const
{
return (safe_cast<const ServerDraftSchematicObjectTemplate*>(getObjectTemplate()))->getSkillCommandsCount();
}
//------------------------------------------------------------------------------
inline int DraftSchematicObject::getItemsPerContainer(void) const
{
return (safe_cast<const ServerDraftSchematicObjectTemplate*>(getObjectTemplate()))->getItemsPerContainer();
}
//------------------------------------------------------------------------------
inline float DraftSchematicObject::getManufactureTime(void) const
{
return (safe_cast<const ServerDraftSchematicObjectTemplate*>(getObjectTemplate()))->getManufactureTime();
}
//------------------------------------------------------------------------------
inline float DraftSchematicObject::getPrototypeTime(void) const
{
return (safe_cast<const ServerDraftSchematicObjectTemplate*>(getObjectTemplate()))->getPrototypeTime();
}
//------------------------------------------------------------------------------
inline bool DraftSchematicObject::mustDestroyIngredients() const
{
return (safe_cast<const ServerDraftSchematicObjectTemplate*>(getObjectTemplate()))->getDestroyIngredients();
}
//========================================================================
#endif // INCLUDED_DraftSchematicObject_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,112 @@
// ======================================================================
//
// FactoryObject.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_FactoryObject_H
#define INCLUDED_FactoryObject_H
#include "serverGame/ManufactureObjectInterface.h"
#include "serverGame/TangibleObject.h"
#include "Archive/AutoDeltaMap.h"
class ServerFactoryObjectTemplate;
class FactoryObject : public TangibleObject, public ManufactureObjectInterface
{
public:
typedef std::map<StringId, float> AttribMap;
typedef std::vector<StringId> StringIdList;
explicit FactoryObject(const ServerFactoryObjectTemplate* newTemplate);
virtual ~FactoryObject();
void initialize(const ManufactureSchematicObject & source);
void calculateAttributes();
bool isFactoryOk() const;
static void removeDefaultTemplate(void);
virtual bool canDestroy() const;
virtual void onContainerTransfer(ServerObject * destination, ServerObject* transferer);
virtual Controller* createDefaultController(void);
void addMembersToPackages ();
virtual void getAttributes (stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const;
bool startCraftingSession(ManufactureSchematicObject & schematic);
bool endCraftingSession();
bool resetCraftingSession();
bool inCraftingSession() const;
bool removeCraftingReferences(int count);
bool addCraftingReferences(int count);
bool addObject();
bool removeObject(ServerObject & destination);
int deleteContents(int count);
bool transferObjects(FactoryObject & toCrate, int objectCount);
FactoryObject * makeCopy(ServerObject & destination, int count, bool destroySource = true);
virtual void onContainedObjectLoaded(const NetworkId &oid);
const char * getContainedTemplateName() const;
const char * getContainedSharedTemplateName() const;
const ObjectTemplate * getContainedObjectTemplate() const;
const TangibleObject * getContainedObject() const;
const std::string & getAppearanceData() const;
const std::string & getItemCustomAppearance() const;
// ManufactureObjectInterface functions
virtual uint32 getDraftSchematic() const;
virtual bool getSlot(int index, Crafting::IngredientSlot & data, bool flag) const;
virtual int getSlotsCount() const;
virtual const AttribMap & getAttributes() const;
virtual void setAttribute(const ServerIntangibleObjectTemplate::SchematicAttribute & attribute);
virtual void setAttribute(const StringId & name, float value);
virtual const AttribMap & getResourceMaxAttributes() const;
virtual void setResourceMaxAttribute(const StringId & name, float value);
virtual const StringIdList & getExperimentAttributeNames() const;
virtual void setExperimentAttribute(const StringId & name, float value);
virtual void getAllExperimentAttributeValues(const StringId & name, float & value, float & minValue, float & maxValue, float & resourceMaxValue) const;
virtual void setExperimentAttributeLimits(const StringId & name, float minValue, float maxValue, float resourceMaxValue);
virtual bool isMakingObject(void) const;
virtual const NetworkId & getDerivedNetworkId() const;
protected:
virtual void initializeFirstTimeObject();
virtual void endBaselines();
virtual void onLoadedFromDatabase();
virtual const SharedObjectTemplate * getDefaultSharedTemplate(void) const;
private:
FactoryObject();
FactoryObject(const FactoryObject& rhs);
FactoryObject& operator=(const FactoryObject& rhs);
TangibleObject * manufactureObject();
void addIdToObjectList(const NetworkId & id);
const NetworkId removeIdFromObjectList(void);
void addIdToPendingList(const NetworkId & id, const ServerObject & destination);
ServerObject * removeIdFromPendingList(const NetworkId & id);
int getPendingListCount() const;
int getObjectListCount() const;
private:
static const SharedObjectTemplate * m_defaultSharedTemplate; // template to use if no shared template is given
mutable bool m_badFactoryLogged; // keep track if we've logged that this factory is bad to reduce spam
// manf schematic data for creating new objects
Archive::AutoDeltaMap<StringId, float> m_attributes;
Archive::AutoDeltaVariable<CachedNetworkId> m_craftingSchematic; // the schematic being used during a crafting session
Archive::AutoDeltaVariable<int> m_craftingCount; // the number of our objects being used in the schematic
};
#endif // INCLUDED_FactoryObject_H
@@ -0,0 +1,47 @@
// ======================================================================
//
// GroupIdObserver.cpp
//
// Copyright 2002 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/GroupIdObserver.h"
#include "serverGame/CreatureObject.h"
#include "serverGame/GroupObject.h"
#include "serverGame/PlayerCreatureController.h"
#include "serverGame/PlayerObject.h"
// ======================================================================
GroupIdObserver::GroupIdObserver(CreatureObject *who, Archive::AutoDeltaObserverOp operation) :
m_profilerBlock("GroupIdObserver"),
m_pvpObserver(who, operation),
m_creature(who),
m_group(who->getGroup())
{
}
// ----------------------------------------------------------------------
GroupIdObserver::~GroupIdObserver()
{
if (m_group && m_creature->getGroup() != m_group)
m_group->removeGroupMember(m_creature->getNetworkId());
if (m_creature->getGroup() != NULL)
{
PlayerObject *playerObject = PlayerCreatureController::getPlayerObject(m_creature);
if ((playerObject != NULL) &&
playerObject->isLookingForGroup())
{
playerObject->setLookingForGroup(false);
}
}
}
// ======================================================================
@@ -0,0 +1,43 @@
// ======================================================================
//
// GroupIdObserver.h
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#ifndef _GroupIdObserver_H_
#define _GroupIdObserver_H_
#include "Archive/AutoDeltaObserverOps.h"
#include "serverGame/PvpUpdateObserver.h"
#include "sharedDebug/Profiler.h"
// ======================================================================
class CreatureObject;
class GroupObject;
// ======================================================================
class GroupIdObserver
{
public:
GroupIdObserver(CreatureObject *who, Archive::AutoDeltaObserverOp operation);
~GroupIdObserver();
private:
GroupIdObserver(GroupIdObserver const &);
GroupIdObserver& operator=(GroupIdObserver const &);
private:
ProfilerAutoBlock m_profilerBlock;
PvpUpdateObserver m_pvpObserver;
CreatureObject *m_creature;
GroupObject *m_group;
};
// ======================================================================
#endif // _GroupIdObserver_H_
@@ -0,0 +1,124 @@
// ======================================================================
//
// GroupMissionCriticalObjectsBuilder.cpp
// asommers
//
// copyright 2004, sony online entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/GroupMissionCriticalObjectsBuilder.h"
#include "serverGame/CreatureObject.h"
#include "serverGame/GroupObject.h"
#include "sharedObject/NetworkIdManager.h"
// ======================================================================
namespace GroupMissionCriticalObjectsBuilderNamespace
{
void buildGroupMissionCriticalObjects(GroupObject const & groupObject, CreatureObject::GroupMissionCriticalObjectSet & groupMissionCriticalObjects);
void buildGroupMissionCriticalObjects(CreatureObject const & creatureObject, CreatureObject::GroupMissionCriticalObjectSet & groupMissionCriticalObjects);
void updateGroupMissionCriticalObjects(GroupObject const & groupObject, CreatureObject::GroupMissionCriticalObjectSet const & groupMissionCriticalObjects);
void updateGroupMissionCriticalObjects(CreatureObject & creatureObject, CreatureObject::GroupMissionCriticalObjectSet const & groupMissionCriticalObjects);
}
using namespace GroupMissionCriticalObjectsBuilderNamespace;
// ======================================================================
// GroupMissionCriticalObjectsBuilderNamespace
// ======================================================================
void GroupMissionCriticalObjectsBuilderNamespace::buildGroupMissionCriticalObjects(GroupObject const & groupObject, CreatureObject::GroupMissionCriticalObjectSet & groupMissionCriticalObjects)
{
GroupObject::GroupMemberVector const & groupMemberVector = groupObject.getGroupMembers();
for (GroupObject::GroupMemberVector::const_iterator groupMemberVectorIter = groupMemberVector.begin(); groupMemberVectorIter != groupMemberVector.end(); ++groupMemberVectorIter)
{
Object const * const object = NetworkIdManager::getObjectById(groupMemberVectorIter->first);
if (!object)
continue;
ServerObject const * serverObject = object->asServerObject();
if (!serverObject)
continue;
CreatureObject const * const creatureObject = serverObject->asCreatureObject();
if (!creatureObject)
continue;
buildGroupMissionCriticalObjects(*creatureObject, groupMissionCriticalObjects);
}
}
// ----------------------------------------------------------------------
void GroupMissionCriticalObjectsBuilderNamespace::buildGroupMissionCriticalObjects(CreatureObject const & creatureObject, CreatureObject::GroupMissionCriticalObjectSet & groupMissionCriticalObjects)
{
CreatureObject::MissionCriticalObjectSet const & missionCriticalObjects = creatureObject.getMissionCriticalObjects();
for (CreatureObject::MissionCriticalObjectSet::const_iterator missionCriticalObjectsIter = missionCriticalObjects.begin(); missionCriticalObjectsIter != missionCriticalObjects.end(); ++missionCriticalObjectsIter)
groupMissionCriticalObjects.insert(std::make_pair(creatureObject.getNetworkId(), *missionCriticalObjectsIter));
}
// ----------------------------------------------------------------------
void GroupMissionCriticalObjectsBuilderNamespace::updateGroupMissionCriticalObjects(GroupObject const & groupObject, CreatureObject::GroupMissionCriticalObjectSet const & groupMissionCriticalObjects)
{
GroupObject::GroupMemberVector const & groupMemberVector = groupObject.getGroupMembers();
for (GroupObject::GroupMemberVector::const_iterator groupMemberVectorIter = groupMemberVector.begin(); groupMemberVectorIter != groupMemberVector.end(); ++groupMemberVectorIter)
{
Object * const object = NetworkIdManager::getObjectById(groupMemberVectorIter->first);
if (!object)
continue;
ServerObject * serverObject = object->asServerObject();
if (!serverObject)
continue;
CreatureObject * const creatureObject = serverObject->asCreatureObject();
if (!creatureObject)
continue;
updateGroupMissionCriticalObjects(*creatureObject, groupMissionCriticalObjects);
}
}
// ----------------------------------------------------------------------
void GroupMissionCriticalObjectsBuilderNamespace::updateGroupMissionCriticalObjects(CreatureObject & creatureObject, CreatureObject::GroupMissionCriticalObjectSet const & groupMissionCriticalObjects)
{
if (creatureObject.isAuthoritative())
creatureObject.setGroupMissionCriticalObjects(groupMissionCriticalObjects);
}
// ======================================================================
// PUBLIC GroupMissionCriticalObjectsBuilder
// ======================================================================
void GroupMissionCriticalObjectsBuilder::updateGroupMissionCriticalObjects(GroupObject const & groupObject)
{
CreatureObject::GroupMissionCriticalObjectSet groupMissionCriticalObjects;
buildGroupMissionCriticalObjects(groupObject, groupMissionCriticalObjects);
GroupMissionCriticalObjectsBuilderNamespace::updateGroupMissionCriticalObjects(groupObject, groupMissionCriticalObjects);
}
// ----------------------------------------------------------------------
void GroupMissionCriticalObjectsBuilder::updateGroupMissionCriticalObjects(CreatureObject & creatureObject, bool const updateGroup)
{
GroupObject const * const groupObject = creatureObject.getGroup();
if (groupObject && updateGroup)
{
CreatureObject::GroupMissionCriticalObjectSet groupMissionCriticalObjects;
buildGroupMissionCriticalObjects(*groupObject, groupMissionCriticalObjects);
GroupMissionCriticalObjectsBuilderNamespace::updateGroupMissionCriticalObjects(*groupObject, groupMissionCriticalObjects);
}
else
{
CreatureObject::GroupMissionCriticalObjectSet groupMissionCriticalObjects;
buildGroupMissionCriticalObjects(creatureObject, groupMissionCriticalObjects);
GroupMissionCriticalObjectsBuilderNamespace::updateGroupMissionCriticalObjects(creatureObject, groupMissionCriticalObjects);
}
}
// ======================================================================
@@ -0,0 +1,31 @@
// ======================================================================
//
// GroupMissionCriticalObjectsBuilder.h
// asommers
//
// copyright 2004, sony online entertainment
//
// ======================================================================
#ifndef INCLUDED_GroupMissionCriticalObjectsBuilder_H
#define INCLUDED_GroupMissionCriticalObjectsBuilder_H
// ======================================================================
class CreatureObject;
class GroupObject;
class NetworkId;
// ======================================================================
class GroupMissionCriticalObjectsBuilder
{
public:
static void updateGroupMissionCriticalObjects(GroupObject const & groupObject);
static void updateGroupMissionCriticalObjects(CreatureObject & creatureObject, bool updateGroup);
};
// ======================================================================
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,208 @@
//========================================================================
//
// GroupObject.h
//
// Copyright 2002 Sony Online Entertainment
//
//========================================================================
#ifndef INCLUDED_GroupObject_H
#define INCLUDED_GroupObject_H
// ======================================================================
#include "serverGame/UniverseObject.h"
#include "Archive/AutoDeltaVariableObserver.h"
#include "Archive/AutoDeltaVectorObserver.h"
#include "serverGame/GroupUpdateObserver.h"
#include "sharedMathArchive/VectorArchive.h"
// ======================================================================
class GroupMemberParam;
class ServerGroupObjectTemplate;
// ======================================================================
class GroupObject: public UniverseObject
{
public:
typedef stdvector<GroupMemberParam>::fwd GroupMemberParamVector;
GroupObject(ServerGroupObjectTemplate const *newTemplate);
virtual ~GroupObject();
virtual GroupObject *asGroupObject();
virtual GroupObject const *asGroupObject() const;
virtual Controller * createDefaultController ();
virtual void setupUniverse ();
virtual bool isVisibleOnClient (const Client &client) const;
virtual void getAttributes (AttributeVector &data) const;
static void removeDefaultTemplate ();
static void createGroup (GroupMemberParam const & leader, GroupMemberParamVector const & members);
static void onChatRoomCreate (std::string const &path);
static void onVoiceChatRoomCreate (std::string const &channelName);
static void addToLeaderMap (NetworkId const &leaderId, NetworkId const &groupId);
static void removeFromLeaderMap (NetworkId const &leaderId, NetworkId const &groupId);
static NetworkId getGroupIdForLeader (NetworkId const &leaderId);
static void createAllGroupChatRooms ();
static int maximumMembersInGroup();
typedef std::pair<NetworkId, std::string> GroupMember;
typedef stdvector<GroupMember>::fwd GroupMemberVector;
typedef std::pair<NetworkId /*ship*/, int /*formation slot*/> GroupShipFormationMember;
typedef std::pair<NetworkId /*POB ship*/, NetworkId /*owner of the POB*/> GroupPOBShipAndOwner;
std::string const & getGroupName () const;
void getGroupMemberIds (stdvector<NetworkId>::fwd &members) const;
NetworkId const & getGroupLeaderId () const;
std::string const & getGroupLeaderName () const;
bool isGroupFull () const;
int getPCMemberCount () const;
bool isMemberPC(NetworkId const & memberId) const;
bool doesGroupHaveRoomFor(int additionalMembers) const;
GroupMemberVector const & getGroupMembers () const;
int getGroupLevel () const;
uint32 getFormationNameCrc() const;
void setGroupName (std::string const &groupName);
void makeLeader (NetworkId const &newLeaderId);
void addGroupMember (GroupMemberParam const & member);
GroupMemberParam const createGroupMemberParamForMember(NetworkId const &memberId) const;
void removeGroupMember (NetworkId const &memberId);
bool isGroupMember (NetworkId const &memberId) const;
void disbandGroup ();
void sendGroupChat (NetworkId const &memberId, Unicode::String const &text) const;
void setMemberLevel(NetworkId const &memberId, int level);
void setMemberProfession(NetworkId const &memberId, uint8 profession);
void onGroupMemberConnect(NetworkId const &memberId);
void onGroupMemberRemoved(NetworkId const &memberId, bool disbanding);
void setFormationNameCrc (uint32 formationNameCrc);
void setShipForMember(NetworkId const & memberId, NetworkId const & shipId);
void setShipFormationSlotForMember(NetworkId const & memberId, int const formationSlot);
void addPOBShipAndOwner(NetworkId const & shipId, NetworkId const & ownerId);
void removePOBShip(NetworkId const & shipId);
NetworkId const & getPOBShipOwnedByMember(NetworkId const & memberId) const;
NetworkId const & getPOBShipMemberIsContainedIn(NetworkId const & memberId) const;
NetworkId const & getMemberShip(NetworkId const & memberId) const;
bool getShipIsPOB(NetworkId const & shipId) const;
std::string const & getMemberName(NetworkId const & memberId) const;
int getMemberLevel(NetworkId const & memberId) const;
int getMemberLevelByMemberIndex(unsigned int memberIndex) const;
uint8 getMemberProfession(NetworkId const & memberId) const;
uint8 getMemberProfessionByMemberIndex(unsigned int memberIndex) const;
NetworkId const & getLootMasterId() const;
void makeLootMaster(NetworkId const & newLootMasterId);
int getLootRule() const;
void setLootRule(int const rule);
std::pair<int32, int32> const & getGroupPickupTimer() const;
unsigned int getSecondsLeftOnGroupPickup() const;
void setGroupPickupTimer(time_t startTime, time_t endTime);
std::pair<std::string, Vector> const & getGroupPickupLocation() const;
void setGroupPickupLocation(std::string const & planetName, Vector const & location);
void reenterGroupChatRoom(CreatureObject const &who) const;
protected:
virtual SharedObjectTemplate const *getDefaultSharedTemplate() const;
private:
GroupObject();
GroupObject(GroupObject const &rhs);
GroupObject& operator=(GroupObject const &rhs);
void addMembersToPackages();
std::string getChatRoomPath() const;
std::string getVoiceChatDisplayName() const;
std::string getChatName(std::string const &memberName) const;
void createGroupChatRoom() const;
void destroyGroupChatRoom() const;
void addToGroupChatRoom(std::string const &memberName) const;
void addToGroupVoiceChatRoom(NetworkId const & memberId, std::string const &memberName) const;
void removeFromGroupChatRoom(std::string const &memberName) const;
void removeFromGroupVoiceChatRoom(NetworkId const & memberId, std::string const &memberName) const;
void onGroupChatRoomCreated();
void onGroupVoiceChatRoomCreated();
bool chatRoomCreated() const;
void setChatRoomCreated();
void calcGroupLevel();
private:
static const SharedObjectTemplate * m_defaultSharedTemplate; // template to use if no shared template is given
Archive::AutoDeltaVariable<std::string> m_groupName;
Archive::AutoDeltaVectorObserver<GroupMember, GroupUpdateObserver, GroupObject> m_groupMembers;
Archive::AutoDeltaVectorObserver<GroupShipFormationMember, GroupUpdateObserver, GroupObject> m_groupShipFormationMembers;
Archive::AutoDeltaVectorObserver<GroupPOBShipAndOwner, GroupUpdateObserver, GroupObject> m_groupPOBShipAndOwners;
Archive::AutoDeltaVariable<int16> m_groupLevel;
Archive::AutoDeltaVector<int16> m_groupMemberLevels;
Archive::AutoDeltaVector<uint8> m_groupMemberProfessions;
Archive::AutoDeltaVariable<uint32> m_formationNameCrc;
Archive::AutoDeltaSet<NetworkId> m_allMembers;
Archive::AutoDeltaSet<NetworkId> m_nonPCMembers;
Archive::AutoDeltaVariableObserver<NetworkId, GroupUpdateObserver, GroupObject> m_lootMaster;
Archive::AutoDeltaVariable<uint32> m_lootRule;
Archive::AutoDeltaVariable<std::pair<int32, int32> > m_groupPickupTimer; // <start time_t, end time_t> (may not be 0, but if the end time is < the current time, it means no group pickup is currently active)>
Archive::AutoDeltaVariable<std::pair<std::string, Vector> > m_groupPickupLocation; // planet/zone name, and (x,y,z) world location
};
// ======================================================================
inline std::string const &GroupObject::getGroupName() const
{
return m_groupName.get();
}
// ----------------------------------------------------------------------
inline GroupObject::GroupMemberVector const &GroupObject::getGroupMembers() const
{
return m_groupMembers.get();
}
//----------------------------------------------------------------------
inline int GroupObject::getGroupLevel () const
{
return m_groupLevel.get ();
}
//----------------------------------------------------------------------
inline uint32 GroupObject::getFormationNameCrc () const
{
return m_formationNameCrc.get();
}
// ----------------------------------------------------------------------
inline bool GroupObject::isGroupMember(NetworkId const &memberId) const
{
return m_allMembers.contains(memberId);
}
// ----------------------------------------------------------------------
inline std::pair<int32, int32> const & GroupObject::getGroupPickupTimer() const
{
return m_groupPickupTimer.get();
}
// ----------------------------------------------------------------------
inline std::pair<std::string, Vector> const & GroupObject::getGroupPickupLocation() const
{
return m_groupPickupLocation.get();
}
// ======================================================================
#endif
@@ -0,0 +1,54 @@
// ======================================================================
//
// GroupStringId.h
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#ifndef _GroupStringId_H_
#define _GroupStringId_H_
// ======================================================================
namespace GroupStringId
{
const StringId SID_GROUP_MUST_BE_LEADER ("group", "must_be_leader");
const StringId SID_GROUP_FULL ("group", "full");
const StringId SID_GROUP_ALREADY_GROUPED ("group", "already_grouped");
const StringId SID_GROUP_CONSIDERING_YOUR_GROUP ("group", "considering_your_group");
const StringId SID_GROUP_CONSIDERING_OTHER_GROUP ("group", "considering_other_group");
const StringId SID_GROUP_INVITE_LEADER ("group", "invite_leader");
const StringId SID_GROUP_INVITE_TARGET ("group", "invite_target");
const StringId SID_GROUP_INVITE_NO_TARGET_SELF ("group", "invite_no_target_self");
const StringId SID_GROUP_MUST_BE_INVITED ("group", "must_be_invited");
const StringId SID_GROUP_DECLINE_SELF ("group", "decline_self");
const StringId SID_GROUP_DECLINE_LEADER ("group", "decline_leader");
const StringId SID_GROUP_UNINVITE_SELF ("group", "uninvite_self");
const StringId SID_GROUP_UNINVITE_TARGET ("group", "uninvite_target");
const StringId SID_GROUP_UNINVITE_NOT_INVITED ("group", "uninvite_not_invited");
const StringId SID_GROUP_UNINVITE_NO_TARGET_SELF ("group", "uninvite_no_target_self");
const StringId SID_GROUP_NEW_LEADER ("group", "new_leader");
const StringId SID_GROUP_NEW_MASTER_LOOTER ("group", "new_master_looter");
const StringId SID_GROUP_FORMED ("group", "formed_self");
const StringId SID_GROUP_JOIN ("group", "joined_self");
const StringId SID_GROUP_DISBANDED ("group", "disbanded");
const StringId SID_GROUP_REMOVED ("group", "removed");
const StringId SID_GROUP_MUST_EJECT_FIRST ("group", "must_eject_first");
const StringId SID_GROUP_ONLY_PLAYERS_IN_SPACE ("group", "only_players_in_space");
const StringId SID_GROUP_NO_DISBAND_OWNER ("group", "no_disband_owner");
const StringId SID_GROUP_NO_KICK_FROM_SHIP_OWNER ("group", "no_kick_from_ship_owner");
const StringId SID_GROUP_BEASTS_CANT_JOIN ("group", "beasts_cant_join");
const StringId SID_GROUP_EXISTING_GROUP_NOT_FOUND ("group", "existing_group_not_found");
const StringId SID_GROUP_JOIN_INVITER_NOT_LEADER ("group", "join_inviter_not_leader");
const StringId SID_GROUP_JOIN_FULL ("group", "join_full");
const StringId SID_GROUP_INVITE_IN_COMBAT ("group", "invite_in_combat");
const StringId SID_GROUP_INVITE_TARGET_IN_COMBAT ("group", "invite_target_in_combat");
const StringId SID_GROUP_JOIN_IN_COMBAT ("group", "join_in_combat");
const StringId SID_GROUP_JOIN_LEADER_IN_COMBAT ("group", "join_leader_in_combat");
}
// ======================================================================
#endif // _GroupStringId_H_
@@ -0,0 +1,230 @@
// ======================================================================
//
// GroupUpdateObserver.cpp
//
// Copyright 2002 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/GroupUpdateObserver.h"
#include "UnicodeUtils.h"
#include "serverGame/Chat.h"
#include "serverGame/Client.h"
#include "serverGame/CreatureObject.h"
#include "serverGame/GroupMissionCriticalObjectsBuilder.h"
#include "serverGame/GroupWaypointBuilder.h"
#include "serverGame/GroupObject.h"
#include "serverGame/GroupStringId.h"
#include "serverGame/ObserveTracker.h"
#include "serverScript/GameScriptObject.h"
#include "serverScript/ScriptParameters.h"
#include "sharedGame/ProsePackage.h"
#include "sharedObject/NetworkIdManager.h"
// ======================================================================
static std::set<GroupObject const *> s_activeUpdaters;
// ======================================================================
inline CreatureObject *findCreatureById(NetworkId const &networkId)
{
Object *obj = NetworkIdManager::getObjectById(networkId);
if (obj)
{
ServerObject *serverObj = obj->asServerObject();
if (serverObj)
return serverObj->asCreatureObject();
}
return 0;
}
// ======================================================================
GroupUpdateObserver::GroupUpdateObserver(GroupObject *group, Archive::AutoDeltaObserverOp) :
m_profilerBlock("GroupUpdateObserver"),
m_group(0),
m_members(),
m_leaderId(NetworkId::cms_invalid),
m_lootMasterId()
{
if (!group || s_activeUpdaters.find(group) != s_activeUpdaters.end())
return;
m_group = group;
s_activeUpdaters.insert(group);
group->getGroupMemberIds(m_members);
m_leaderId = group->getGroupLeaderId();
m_lootMasterId = group->getLootMasterId();
}
// ----------------------------------------------------------------------
GroupUpdateObserver::~GroupUpdateObserver()
{
if (!m_group)
return;
s_activeUpdaters.erase(m_group);
std::vector<NetworkId> newMembers;
m_group->getGroupMemberIds(newMembers);
NetworkId const &newLeaderId = m_group->getGroupLeaderId();
// leader change notifications
{
if (newLeaderId != m_leaderId)
{
// script triggers on old and new leaders
if (m_leaderId != NetworkId::cms_invalid)
{
GroupObject::removeFromLeaderMap(m_leaderId, m_group->getNetworkId());
CreatureObject *oldLeaderCreature = findCreatureById(m_leaderId);
if (oldLeaderCreature && oldLeaderCreature->isAuthoritative() && oldLeaderCreature->getScriptObject())
{
ScriptParams scriptParams;
scriptParams.addParam(m_group->getNetworkId());
scriptParams.addParam(newLeaderId);
scriptParams.addParam(m_leaderId);
IGNORE_RETURN(oldLeaderCreature->getScriptObject()->trigAllScripts(Scripting::TRIG_GROUP_LEADER_CHANGED, scriptParams));
}
}
if (newLeaderId != NetworkId::cms_invalid)
{
GroupObject::addToLeaderMap(newLeaderId, m_group->getNetworkId());
CreatureObject *newLeaderCreature = findCreatureById(newLeaderId);
if (newLeaderCreature && newLeaderCreature->isAuthoritative() && newLeaderCreature->getScriptObject())
{
ScriptParams scriptParams;
scriptParams.addParam(m_group->getNetworkId());
scriptParams.addParam(newLeaderId);
scriptParams.addParam(m_leaderId);
IGNORE_RETURN(newLeaderCreature->getScriptObject()->trigAllScripts(Scripting::TRIG_GROUP_LEADER_CHANGED, scriptParams));
}
}
// messages to group members if there was a leader before
if (m_leaderId != NetworkId::cms_invalid)
{
ProsePackage pp;
pp.stringId = GroupStringId::SID_GROUP_NEW_LEADER;
pp.actor.str = Unicode::narrowToWide(m_group->getGroupLeaderName());
for (std::vector<NetworkId>::iterator i = newMembers.begin(); i != newMembers.end(); ++i)
{
CreatureObject *creature = findCreatureById(*i);
if (creature && creature->isAuthoritative())
Chat::sendSystemMessage(*creature, pp);
}
}
}
NetworkId const & newLootMasterId = m_group->getLootMasterId();
if ((m_lootMasterId != newLootMasterId) && (newLootMasterId.isValid()))
{
ProsePackage pp;
pp.stringId = GroupStringId::SID_GROUP_NEW_MASTER_LOOTER;
pp.actor.str = Unicode::narrowToWide(m_group->getMemberName(newLootMasterId));
for (std::vector<NetworkId>::iterator i = newMembers.begin(); i != newMembers.end(); ++i)
{
CreatureObject * const creature = findCreatureById(*i);
if (creature && creature->isAuthoritative())
Chat::sendSystemMessage(*creature, pp);
}
}
}
// gather any people removed from the group in delMembers
// and pare down newMembers to only those added to the group
std::vector<NetworkId> delMembers;
{
for (std::vector<NetworkId>::iterator i = m_members.begin(); i != m_members.end(); ++i)
{
bool found = false;
for (std::vector<NetworkId>::iterator j = newMembers.begin(); j != newMembers.end(); ++j)
{
if (*i == *j)
{
found = true;
newMembers.erase(j);
break;
}
}
if (!found)
delMembers.push_back(*i);
}
}
// If the group member list has changed, notify all the current and former group members
if (!delMembers.empty() || !newMembers.empty())
{
// Grab the list of current members
std::vector<NetworkId> currentMembers;
m_group->getGroupMemberIds(currentMembers);
// Create a combined list of members that includes both the current members and the deleted members
std::vector<NetworkId> currentAndDeletedGroupMembers(currentMembers.begin(), currentMembers.end());
currentAndDeletedGroupMembers.insert(currentAndDeletedGroupMembers.end(), delMembers.begin(), delMembers.end());
// Tell all the group members (both past and present) about the group member change
std::vector<NetworkId>::const_iterator i;
for (i = currentAndDeletedGroupMembers.begin(); i != currentAndDeletedGroupMembers.end(); ++i)
{
CreatureObject *creature = findCreatureById(*i);
if (creature && creature->isAuthoritative() && creature->getScriptObject())
{
ScriptParams scriptParams;
scriptParams.addParam(m_group->getNetworkId());
scriptParams.addParam(currentMembers); // current group members
scriptParams.addParam(newMembers); // the added group members
scriptParams.addParam(delMembers); // the removed group members
IGNORE_RETURN(creature->getScriptObject()->trigAllScripts(Scripting::TRIG_GROUP_MEMBERS_CHANGED, scriptParams));
}
}
}
// have removed members with clients unobserve the group object, and get remove or disband messages
{
bool disbanding = newLeaderId == NetworkId::cms_invalid;
for (std::vector<NetworkId>::iterator i = delMembers.begin(); i != delMembers.end(); ++i)
m_group->onGroupMemberRemoved(*i, disbanding);
}
// have new members with clients observe the group object, and get join or formed messages
{
for (std::vector<NetworkId>::iterator i = newMembers.begin(); i != newMembers.end(); ++i)
{
CreatureObject *creature = findCreatureById(*i);
if (creature && creature->isAuthoritative())
{
creature->setGroup(m_group, true);
if (creature->getScriptObject())
{
ScriptParams scriptParams;
scriptParams.addParam(m_group->getNetworkId());
IGNORE_RETURN(creature->getScriptObject()->trigAllScripts(Scripting::TRIG_ADDED_TO_GROUP, scriptParams));
if ((*i) == newLeaderId)
{
IGNORE_RETURN(creature->getScriptObject()->trigAllScripts(Scripting::TRIG_GROUP_FORMED, scriptParams));
}
}
Client *client = creature->getClient();
if (client)
{
ObserveTracker::onClientJoinedGroup(*client, *m_group);
ProsePackage pp;
pp.stringId = (*i) == newLeaderId ? GroupStringId::SID_GROUP_FORMED : GroupStringId::SID_GROUP_JOIN;
Chat::sendSystemMessage(*creature, pp);
}
}
}
}
GroupMissionCriticalObjectsBuilder::updateGroupMissionCriticalObjects(*m_group);
GroupWaypointBuilder::updateGroupWaypoints(*m_group);
}
// ======================================================================
@@ -0,0 +1,45 @@
// ======================================================================
//
// GroupUpdateObserver.h
//
// Copyright 2002 Sony Online Entertainment
//
// ======================================================================
#ifndef _GroupUpdateObserver_H_
#define _GroupUpdateObserver_H_
// ======================================================================
#include "Archive/AutoDeltaObserverOps.h"
#include "sharedFoundation/NetworkId.h"
#include "sharedDebug/Profiler.h"
// ======================================================================
class GroupObject;
// ======================================================================
class GroupUpdateObserver
{
public:
explicit GroupUpdateObserver(GroupObject *group, Archive::AutoDeltaObserverOp operation);
~GroupUpdateObserver();
private:
GroupUpdateObserver(GroupUpdateObserver const &);
GroupUpdateObserver &operator=(GroupUpdateObserver const &);
private:
ProfilerAutoBlock m_profilerBlock;
GroupObject *m_group;
std::vector<NetworkId> m_members;
NetworkId m_leaderId;
NetworkId m_lootMasterId;
};
// ======================================================================
#endif // _GroupUpdateObserver_H_
@@ -0,0 +1,148 @@
// ======================================================================
//
// GroupWaypointBuilder.cpp
//
// Copyright 2004 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/GroupWaypointBuilder.h"
#include "serverGame/ConfigServerGame.h"
#include "serverGame/CreatureObject.h"
#include "serverGame/GroupObject.h"
#include "serverGame/PlayerCreatureController.h"
#include "serverGame/PlayerObject.h"
#include "sharedUtility/Location.h"
#include "sharedObject/NetworkIdManager.h"
// ======================================================================
namespace GroupWaypointBuilderNamespace
{
void buildGroupWaypoints(GroupObject const &groupObject, PlayerObject::WaypointMap &groupWaypoints);
void buildGroupWaypoints(PlayerObject const &playerObject, PlayerObject::WaypointMap &groupWaypoints);
void updateGroupWaypoints(GroupObject const &groupObject, PlayerObject::WaypointMap const &groupWaypoints);
void updateGroupWaypoints(PlayerObject &playerObject, PlayerObject::WaypointMap const &groupWaypoints);
}
using namespace GroupWaypointBuilderNamespace;
// ======================================================================
// GroupWaypointBuilderNamespace
// ======================================================================
void GroupWaypointBuilderNamespace::buildGroupWaypoints(GroupObject const &groupObject, PlayerObject::WaypointMap &groupWaypoints)
{
GroupObject::GroupMemberVector const & groupMemberVector = groupObject.getGroupMembers();
for (GroupObject::GroupMemberVector::const_iterator groupMemberVectorIter = groupMemberVector.begin(); groupMemberVectorIter != groupMemberVector.end(); ++groupMemberVectorIter)
{
Object const * const object = NetworkIdManager::getObjectById(groupMemberVectorIter->first);
if (!object)
continue;
ServerObject const * serverObject = object->asServerObject();
if (!serverObject || !serverObject->isPlayerControlled())
continue;
CreatureObject const * const creatureObject = serverObject->asCreatureObject();
if (!creatureObject)
continue;
PlayerObject const * const playerObject = PlayerCreatureController::getPlayerObject(creatureObject);
if (!playerObject)
continue;
buildGroupWaypoints(*playerObject, groupWaypoints);
}
}
// ----------------------------------------------------------------------
void GroupWaypointBuilderNamespace::buildGroupWaypoints(PlayerObject const &playerObject, PlayerObject::WaypointMap &groupWaypoints)
{
PlayerObject::WaypointMap const &waypoints = playerObject.getWaypoints();
if (!waypoints.empty())
{
for (PlayerObject::WaypointMap::const_iterator i = waypoints.begin(); i != waypoints.end(); ++i)
if ((*i).second.isActive() && !strcmp((*i).second.getLocation().getSceneId(), ConfigServerGame::getSceneID()))
groupWaypoints[(*i).first] = (*i).second;
}
}
// ----------------------------------------------------------------------
void GroupWaypointBuilderNamespace::updateGroupWaypoints(GroupObject const &groupObject, PlayerObject::WaypointMap const &groupWaypoints)
{
GroupObject::GroupMemberVector const &groupMemberVector = groupObject.getGroupMembers();
for (GroupObject::GroupMemberVector::const_iterator groupMemberVectorIter = groupMemberVector.begin(); groupMemberVectorIter != groupMemberVector.end(); ++groupMemberVectorIter)
{
Object * const object = NetworkIdManager::getObjectById(groupMemberVectorIter->first);
if (!object)
continue;
ServerObject * const serverObject = object->asServerObject();
if (!serverObject || !serverObject->isPlayerControlled())
continue;
CreatureObject * const creatureObject = serverObject->asCreatureObject();
if (!creatureObject)
continue;
PlayerObject * const playerObject = PlayerCreatureController::getPlayerObject(creatureObject);
if (!playerObject)
continue;
updateGroupWaypoints(*playerObject, groupWaypoints);
}
}
// ----------------------------------------------------------------------
void GroupWaypointBuilderNamespace::updateGroupWaypoints(PlayerObject &playerObject, PlayerObject::WaypointMap const &groupWaypoints)
{
if (playerObject.isAuthoritative())
playerObject.setGroupWaypoints(groupWaypoints);
}
// ======================================================================
// PUBLIC GroupWaypointBuilder
// ======================================================================
void GroupWaypointBuilder::updateGroupWaypoints(GroupObject const &groupObject)
{
#if 0
PlayerObject::WaypointMap groupWaypoints;
buildGroupWaypoints(groupObject, groupWaypoints);
GroupWaypointBuilderNamespace::updateGroupWaypoints(groupObject, groupWaypoints);
#endif
}
// ----------------------------------------------------------------------
void GroupWaypointBuilder::updateGroupWaypoints(PlayerObject &playerObject, bool const updateGroup)
{
#if 0
CreatureObject const * const creatureObject = playerObject.getCreatureObject();
if (creatureObject)
{
GroupObject const * const groupObject = creatureObject->getGroup();
if (groupObject && updateGroup)
{
PlayerObject::WaypointMap groupWaypoints;
buildGroupWaypoints(*groupObject, groupWaypoints);
GroupWaypointBuilderNamespace::updateGroupWaypoints(*groupObject, groupWaypoints);
}
else
{
PlayerObject::WaypointMap groupWaypoints;
buildGroupWaypoints(playerObject, groupWaypoints);
GroupWaypointBuilderNamespace::updateGroupWaypoints(playerObject, groupWaypoints);
}
}
#endif
}
// ======================================================================
@@ -0,0 +1,29 @@
// ======================================================================
//
// GroupWaypointBuilder.h
//
// Copyright 2004 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_GroupWaypointBuilder_H
#define INCLUDED_GroupWaypointBuilder_H
// ======================================================================
class GroupObject;
class PlayerObject;
// ======================================================================
class GroupWaypointBuilder
{
public:
static void updateGroupWaypoints(GroupObject const &groupObject);
static void updateGroupWaypoints(PlayerObject &playerObject, bool updateGroup);
};
// ======================================================================
#endif // INCLUDED_GroupWaypointBuilder_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,210 @@
//========================================================================
//
// GuildObject.h
//
// Copyright 2002 Sony Online Entertainment
//
//========================================================================
#ifndef INCLUDED_GuildObject_H
#define INCLUDED_GuildObject_H
// ======================================================================
#include "Archive/AutoDeltaMap.h"
#include "Archive/AutoDeltaSet.h"
#include "serverGame/GuildInfo.h"
#include "serverGame/GuildMemberInfo.h"
#include "serverGame/UniverseObject.h"
// ======================================================================
class ServerGuildObjectTemplate;
// ======================================================================
class GuildObject: public UniverseObject
{
public:
GuildObject(ServerGuildObjectTemplate const *newTemplate);
virtual ~GuildObject();
virtual Controller* createDefaultController();
virtual void setupUniverse();
virtual bool isVisibleOnClient(const Client &client) const;
virtual void getAttributes(stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const;
virtual void unload();
GuildInfo const * getGuildInfo(int guildId) const;
GuildMemberInfo const * getGuildMemberInfo(int guildId, NetworkId const &memberId) const;
stdset<std::string>::fwd const &getGuildEnemies() const;
void getAllGuildIds(stdvector<int>::fwd &results) const;
int findGuild(std::string const &name) const;
bool guildExists(int guildId) const;
int getGuildId(NetworkId const &memberId) const;
int getGuildIdForSponsored(NetworkId const &memberId) const;
int getGuildIdForGuildLeader(NetworkId const &leaderId) const;
void getGuildMemberIds(int guildId, stdvector<NetworkId>::fwd &results) const;
void getMemberIdsWithPermissions(int guildId, int permissions, stdvector<NetworkId>::fwd &results) const;
int createGuild(std::string const &guildName, std::string const &guildAbbrev, int guildId = 0);
void disbandGuild(int guildId);
void removeGuildMember(int guildId, NetworkId const &memberId);
void addGuildCreatorMember(int guildId, NetworkId const &memberId, std::string const &memberName, std::string const &memberProfessionSkillTemplate, int memberLevel);
void addGuildSponsorMember(int guildId, NetworkId const &memberId, std::string const &memberName, std::string const &memberProfessionSkillTemplate, int memberLevel);
void setGuildMemberPermission(int guildId, NetworkId const &memberId, int permissions);
void setGuildMemberTitle(int guildId, NetworkId const &memberId, std::string const &title);
void setGuildMemberAllegiance(int guildId, NetworkId const &memberId, NetworkId const &allegiance);
void setGuildMemberPermissionAndAllegiance(int guildId, NetworkId const &memberId, int permissions, NetworkId const &allegiance);
void setGuildMemberNameAndPermision(int guildId, NetworkId const &memberId, std::string const &memberName, int permissions);
void setGuildMemberProfessionInfo(int guildId, NetworkId const &memberId, std::string const &memberProfessionSkillTemplate, int memberLevel);
void addGuildMemberRank(int guildId, NetworkId const &memberId, std::string const &rankName);
void removeGuildMemberRank(int guildId, NetworkId const &memberId, std::string const &rankName);
bool hasGuildMemberRank(int guildId, NetworkId const &memberId, std::string const &rankName);
void getGuildMemberRank(int guildId, NetworkId const &memberId, stdvector<std::string>::fwd &ranks);
void setGuildLeader(int guildId, NetworkId const &leaderId);
void setGuildElectionEndTime(int guildId, int electionPreviousEndTime, int electionNextEndTime);
void setGuildFaction(int guildId, uint32 guildFaction);
void setGuildGcwDefenderRegion(int guildId, std::string const &guildGcwDefenderRegion);
void setGuildEnemy(int guildId, int enemyId);
void removeGuildEnemy(int guildId, int enemyId);
void modifyGuildWarKillTracking(int killerGuildId, int victimGuildId, int adjustment, int updateTime);
void updateGuildWarKillTrackingData();
void setGuildName(int guildId, std::string const &newName);
void setGuildAbbrev(int guildId, std::string const &newAbbrev);
void calculateGcwImperialScorePercentileForSwg();
void depersistGcwImperialScorePercentile();
void updateGcwImperialScorePercentile(stdset<std::string>::fwd const & gcwScoreCategories);
void updateGcwRegionDefenderBonus(std::string const & gcwScoreCategory);
std::map<std::string, int> const & getGcwImperialScorePercentile() const;
std::map<std::string, int> const & getGcwGroupImperialScorePercentile() const;
int getGcwImperialScorePercentile(std::string const & gcwCategory) const; // the rebel score is 100 - the imperial score
int getGcwGroupImperialScorePercentile(std::string const & gcwGroup) const; // the rebel score is 100 - the imperial score
float getGcwDefenderRegionImperialBonus(std::string const & gcwScoreCategory) const;
float getGcwDefenderRegionRebelBonus(std::string const & gcwScoreCategory) const;
std::map<std::pair<std::string, std::string>, int> const & getGcwGroupCategoryImperialScoreRaw() const;
std::map<std::string, int> const & getGcwGroupImperialScoreRaw() const;
void setGcwImperialScorePercentileFromOtherGalaxy(std::string const & clusterName, std::map<std::string, int> const & gcwImperialScorePercentile, std::map<std::string, int> const & gcwGroupImperialScorePercentile);
void setGcwRawScoreFromOtherGalaxy(std::string const & clusterName, std::map<std::string, std::pair<int64, int64> > const & gcwImperialScore, std::map<std::string, std::pair<int64, int64> > const & gcwRebelScore);
std::map<std::pair<std::string, int>, uint32> const & getGcwRegionDefenderGuilds() const;
std::map<std::string, std::pair<int, int> > const & getGcwRegionDefenderGuildsCount() const;
int getGcwRegionDefenderGuildsVersion() const;
private:
GuildObject();
GuildObject(GuildObject const &rhs);
GuildObject& operator=(GuildObject const &rhs);
void addMembersToPackages();
int nextFreeGuildId();
void onGuildEnemiesChanged();
void onMembersInfoErase(std::pair<int, NetworkId> const & key, GuildMemberInfo const & value);
void onMembersInfoInsert(std::pair<int, NetworkId> const & key, GuildMemberInfo const & value);
void onMembersInfoSet(std::pair<int, NetworkId> const & key, GuildMemberInfo const & oldValue, GuildMemberInfo const & newValue);
void addGcwRegionDefenderGuild(std::string const & gcwRegion, int guildId, uint32 faction);
void removeGcwRegionDefenderGuild(std::string const & gcwRegion, int guildId, uint32 faction);
private:
// BPM GuildObject : UniverseObject // Begin persisted members
Archive::AutoDeltaSet<std::string> m_names;
Archive::AutoDeltaSet<std::string> m_abbrevs;
Archive::AutoDeltaSet<std::string> m_leaders;
Archive::AutoDeltaSet<std::string> m_members;
Archive::AutoDeltaSet<std::string, GuildObject> m_enemies;
// EPM
// parallel maps to persisted members m_names, m_abbrevs, m_leaders, and m_members that
// will provide access to the data because the data in the persisted members are strings
Archive::AutoDeltaMap<int, GuildInfo> m_guildsInfo; // guild id -> GuildInfo
Archive::AutoDeltaMap<std::pair<int, NetworkId>, GuildMemberInfo, GuildObject> m_membersInfo; // (guild id, member id) -> GuildMemberInfo
Archive::AutoDeltaMap<NetworkId, int> m_fullMembers; // member id -> guild id
Archive::AutoDeltaMap<NetworkId, int> m_sponsoredMembers; // member id -> guild id
Archive::AutoDeltaMap<NetworkId, int> m_guildLeaders; // leader id -> guild id
// GCW score tracking
Archive::AutoDeltaMap<std::string, int> m_gcwImperialScorePercentileThisGalaxy;
Archive::AutoDeltaMap<std::string, std::pair<float, float> > m_gcwRegionDefenderBonus;
Archive::AutoDeltaMap<std::string, int> m_gcwGroupImperialScorePercentileThisGalaxy;
Archive::AutoDeltaMap<std::pair<std::string, int>, int> m_gcwImperialScorePercentileHistoryThisGalaxy;
Archive::AutoDeltaMap<std::pair<std::string, int>, int> m_gcwGroupImperialScorePercentileHistoryThisGalaxy;
Archive::AutoDeltaMap<std::string, int> m_gcwImperialScorePercentileHistoryCountThisGalaxy;
Archive::AutoDeltaMap<std::string, int> m_gcwGroupImperialScorePercentileHistoryCountThisGalaxy;
Archive::AutoDeltaMap<std::pair<std::string, std::string>, int> m_gcwImperialScorePercentileOtherGalaxies;
Archive::AutoDeltaMap<std::pair<std::string, std::string>, int> m_gcwGroupImperialScorePercentileOtherGalaxies;
Archive::AutoDeltaMap<std::pair<std::string, std::string>, int> m_gcwGroupCategoryImperialScoreRawThisGalaxy;
Archive::AutoDeltaMap<std::string, int> m_gcwGroupImperialScoreRawThisGalaxy;
Archive::AutoDeltaMap<std::pair<std::string, std::string>, std::pair<int64, int64> > m_gcwImperialScoreOtherGalaxies;
Archive::AutoDeltaMap<std::pair<std::string, std::string>, std::pair<int64, int64> > m_gcwRebelScoreOtherGalaxies;
int m_lowFreeGuildId;
unsigned long m_nextGuildWarKillTrackingAdjustmentUpdate;
std::map<std::pair<int, int>, std::pair<int, int> > m_guildWarKillTrackingAdjustment;
Archive::AutoDeltaMap<std::pair<std::string, int>, uint32> m_gcwRegionDefenderGuilds;
Archive::AutoDeltaMap<std::string, std::pair<int, int> > m_gcwRegionDefenderGuildsCount;
Archive::AutoDeltaVariable<int> m_gcwRegionDefenderGuildsVersion;
};
// ----------------------------------------------------------------------
inline std::map<std::string, int> const & GuildObject::getGcwImperialScorePercentile() const
{
return m_gcwImperialScorePercentileThisGalaxy.getMap();
}
// ----------------------------------------------------------------------
inline std::map<std::string, int> const & GuildObject::getGcwGroupImperialScorePercentile() const
{
return m_gcwGroupImperialScorePercentileThisGalaxy.getMap();
}
// ----------------------------------------------------------------------
inline std::map<std::pair<std::string, std::string>, int> const & GuildObject::getGcwGroupCategoryImperialScoreRaw() const
{
return m_gcwGroupCategoryImperialScoreRawThisGalaxy.getMap();
}
// ----------------------------------------------------------------------
inline std::map<std::string, int> const & GuildObject::getGcwGroupImperialScoreRaw() const
{
return m_gcwGroupImperialScoreRawThisGalaxy.getMap();
}
// ----------------------------------------------------------------------
inline std::map<std::pair<std::string, int>, uint32> const & GuildObject::getGcwRegionDefenderGuilds() const
{
return m_gcwRegionDefenderGuilds.getMap();
}
// ----------------------------------------------------------------------
inline std::map<std::string, std::pair<int, int> > const & GuildObject::getGcwRegionDefenderGuildsCount() const
{
return m_gcwRegionDefenderGuildsCount.getMap();
}
// ----------------------------------------------------------------------
inline int GuildObject::getGcwRegionDefenderGuildsVersion() const
{
return m_gcwRegionDefenderGuildsVersion.get();
}
// ======================================================================
#endif
@@ -0,0 +1,871 @@
//========================================================================
//
// HarvesterInstallationObject.cpp
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/HarvesterInstallationObject.h"
#include "serverGame/Chat.h"
#include "serverGame/ConfigServerGame.h"
#include "serverGame/ContainerInterface.h"
#include "serverGame/CreatureController.h"
#include "serverGame/CreatureObject.h"
#include "serverGame/HarvesterInstallationController.h"
#include "serverGame/InstallationSynchronizedUi.h"
#include "serverGame/PlanetObject.h"
#include "serverGame/PlayerObject.h"
#include "serverGame/ResourceContainerObject.h"
#include "serverGame/ResourcePoolObject.h"
#include "serverGame/ResourceTypeObject.h"
#include "serverGame/ServerHarvesterInstallationObjectTemplate.h"
#include "serverGame/ServerResourceClassObject.h"
#include "serverGame/ServerUniverse.h"
#include "serverGame/ServerWorld.h"
#include "serverNetworkMessages/MessageToPayload.h"
#include "serverUtility/ServerClock.h"
#include "sharedDebug/Profiler.h"
#include "sharedFoundation/DynamicVariableList.h"
#include "sharedFoundation/GameControllerMessage.h"
#include "sharedGame/SharedStringIds.h"
#include "sharedLog/Log.h"
#include "sharedNetworkMessages/MessageQueueGenericResponse.h"
#include "sharedNetworkMessages/MessageQueueGenericValueType.h"
#include "sharedNetworkMessages/MessageQueueHarvesterResourceData.h"
#include "sharedNetworkMessages/MessageQueueResourceEmptyHopper.h"
#include "sharedObject/AlterResult.h"
#include "sharedObject/NetworkIdManager.h"
#include "sharedUtility/InstallationResourceData.h"
#include "swgServerNetworkMessages/MessageQueueResourceFinishHarvest.h"
#include "swgServerNetworkMessages/MessageQueueResourceSetInstalledEfficiency.h"
#include <stdio.h>
#include <vector>
//-----------------------------------------------------------------------
namespace
{
namespace ObjVars
{
const std::string resource = "resource";
}
}
//----------------------------------------------------------------------
HarvesterInstallationObject::HarvesterInstallationObject(const ServerHarvesterInstallationObjectTemplate* newTemplate) :
InstallationObject(newTemplate),
m_installedEfficiency(0.0f),
m_resourceType(NetworkId::cms_invalid),
m_maxExtractionRate(newTemplate->getMaxExtractionRate()),
m_currentExtractionRate(static_cast<float>(newTemplate->getCurrentExtractionRate())),
m_maxHopperAmount(newTemplate->getMaxHopperSize()),
m_hopperResource(NetworkId::cms_invalid),
m_hopperAmount(0.0f),
m_survey(NULL),
m_surveyTime(0)
{
//Installation objects have real time updated UI
addMembersToPackages();
}
//-----------------------------------------------------------------------
HarvesterInstallationObject::~HarvesterInstallationObject()
{
delete m_survey;
m_survey = NULL;
// m_synchronizedUi deleted by superclass
}
//-----------------------------------------------------------------------
/**
* Creates a default controller for this object.
*
* @return the object's controller
*/
Controller* HarvesterInstallationObject::createDefaultController(void)
{
Controller* _controller = new HarvesterInstallationController(this);
NOT_NULL(_controller);
setController(_controller);
return _controller;
}
// ----------------------------------------------------------------------
/**
* Activate an object as a harvester. Assumes the object has already been
* placed in its intended location.
*/
void HarvesterInstallationObject::activate(const NetworkId &actorId)
{
const ServerObject *actor = safe_cast<const ServerObject*>(NetworkIdManager::getObjectById(actorId));
if (getHopperContents() >= m_maxHopperAmount.get())
{
if (actor)
Chat::sendSystemMessage(*actor,SharedStringIds::harvester_hopper_full,Unicode::String());
return;
}
bool active = isActive();
InstallationObject::activate(actorId);
if (!active && isActive())
{
ResourcePoolObject const * const resourcePool = getSelectedResourcePool();
if (!resourcePool)
{
if (actor)
Chat::sendSystemMessage(*actor,SharedStringIds::harvester_no_resource,Unicode::String());
deactivate();
return;
}
if (resourcePool->isDepleted())
{
if (actor)
Chat::sendSystemMessage(*actor,SharedStringIds::harvester_resource_depleted,Unicode::String());
deactivate();
return;
}
if (ConfigServerGame::getDeactivateHarvesterIfDamaged() && (getDamageTaken() > 0))
{
if (actor)
{
// Send cute breakdown message
float damageScale = 1.0f-(static_cast<float>(getDamageTaken())/static_cast<float>(getMaxHitPoints()));
if (damageScale < 0.25)
Chat::sendSystemMessage(*actor,SharedStringIds::harvester_no_maint_1,Unicode::String());
else if (damageScale < 0.5)
Chat::sendSystemMessage(*actor,SharedStringIds::harvester_no_maint_2,Unicode::String());
else if (damageScale < 0.75)
Chat::sendSystemMessage(*actor,SharedStringIds::harvester_no_maint_3,Unicode::String());
else
Chat::sendSystemMessage(*actor,SharedStringIds::harvester_no_maint_4,Unicode::String());
}
deactivate();
}
Vector location(getTransform_o2p().getPosition_p());
//apply current extraction rate multplier for things like harvester bonus
m_installedEfficiency = (m_currentExtractionRate.get() * ConfigServerGame::getHarvesterExtractionRateMultiplier()) * resourcePool->getEfficiencyAtLocation(location.x,location.z);
setTickCount(static_cast<float>(ServerClock::getInstance().getGameTimeSeconds()));
}
}
// ----------------------------------------------------------------------
/**
* Deactivate an object as a harvester.
*/
void HarvesterInstallationObject::deactivate()
{
bool active = isActive();
InstallationObject::deactivate();
if (active && !isActive())
{
m_installedEfficiency=0.0f;
roundHopperContents(); // fractional units are discarded when harvester is deactivated
}
}
// ----------------------------------------------------------------------
void HarvesterInstallationObject::harvest()
{
if (isAuthoritative() && isActive())
{
if (m_installedEfficiency.get() == 0)
return;
if (ConfigServerGame::getDeactivateHarvesterIfDamaged() && (getDamageTaken() > 0))
deactivate();
else
{
ResourcePoolObject const * const pool=getSelectedResourcePool();
if (pool)
{
float condition = static_cast<float>(getMaxHitPoints() - getDamageTaken()) / static_cast<float>(getMaxHitPoints());
DEBUG_FATAL(condition < 0 || condition > 1, ("Condition was %f, should have been between 0 and 1\n",condition));
if (condition< 0 || condition > 1)
condition = 0;
float oldTickCount = getTickCount();
float amountCollected = (pool->harvest(m_installedEfficiency.get(), static_cast<uint32>(getTickCount()))) * condition;
float newTickCount = static_cast<float>(ServerClock::getInstance().getGameTimeSeconds());
setTickCount(newTickCount);
// Check for out of power
if ((getOutOfPowerTime() > 0) && (getOutOfPowerTime() < newTickCount))
{
if (getOutOfPowerTime() < oldTickCount)
{
amountCollected = 0;
}
else
{
float runRatio = (getOutOfPowerTime() - oldTickCount) / (newTickCount - oldTickCount);
DEBUG_REPORT_LOG(true,("Scaling output by %f because power ran out.\n",runRatio));
amountCollected *= runRatio;
}
deactivate();
LOG("CustomerService", ("Power:shut down installation %s owned by %s due to 0 power", getNetworkId().getValueString().c_str(), PlayerObject::getAccountDescription(getOwnerId()).c_str()));
}
int hopperContents=static_cast<int>(getHopperContents());
if (hopperContents + amountCollected > m_maxHopperAmount.get())
{
addResource(m_resourceType.get(),static_cast<float>(m_maxHopperAmount.get()-hopperContents));
deactivate();
}
else
{
addResource(m_resourceType.get(),amountCollected);
}
}
if (!pool || pool->isDepleted())
{
deactivate();
}
}
}
InstallationObject::harvest();
}
//----------------------------------------------------------------------
void HarvesterInstallationObject::selectResource (const NetworkId & resourceTypeId, const NetworkId &actor)
{
if (isAuthoritative())
{
bool found=false;
std::vector<NetworkId> pools;
if (!m_survey)
takeSurvey();
NOT_NULL(m_survey);
for (std::vector<ResourceTypeObject const *>::iterator i=m_survey->begin(); i!=m_survey->end(); ++i)
{
if (*i && (*i)->getNetworkId()==resourceTypeId)
found=true;
}
if (!found)
{
return;
}
if (isActive())
{
deactivate();
m_resourceType = resourceTypeId;
activate(actor);
}
else
m_resourceType = resourceTypeId;
scheduleForAlter();
}
else
{
//TODO: network message
}
}
// ----------------------------------------------------------------------
/**
* Record all the available resource pools. This data is cached but not persisted.
*/
void HarvesterInstallationObject::takeSurvey()
{
if (m_survey)
m_survey->clear();
else
m_survey = new std::vector<ResourceTypeObject const *>;
PlanetObject *planet=ServerUniverse::getInstance().getCurrentPlanet();
if (!planet)
{
WARNING (true, ("Cannot take survey if no planet object exists."));
return;
}
const ResourceClassObject *resClass = getMasterClass();
if (resClass)
planet->getAvailableResourceList(*m_survey, *resClass);
m_surveyTime = ServerClock::getInstance().getGameTimeSeconds();
InstallationSynchronizedUi * const syncUi = dynamic_cast<InstallationSynchronizedUi *>(getSynchronizedUi ());
if (syncUi)
syncUi->resetResourcePools ();
}
//----------------------------------------------------------------------
ServerSynchronizedUi * HarvesterInstallationObject::createSynchronizedUi ()
{
return new InstallationSynchronizedUi(*this);
}
//----------------------------------------------------------------------
void HarvesterInstallationObject::getResourceData (ResourceDataVector & data)
{
InstallationSynchronizedUi * const syncUi = dynamic_cast<InstallationSynchronizedUi *>(getSynchronizedUi ());
if (syncUi)
syncUi->getResourceData (data);
}
// ----------------------------------------------------------------------
int HarvesterInstallationObject::getMaxExtractionRate() const
{
return m_maxExtractionRate.get();
}
// ----------------------------------------------------------------------
float HarvesterInstallationObject::getCurrentExtractionRate() const
{
return m_currentExtractionRate.get();
}
// ----------------------------------------------------------------------
float HarvesterInstallationObject::getInstalledExtractionRate() const
{
return m_installedEfficiency.get(); //TODO: rename ?
}
// ----------------------------------------------------------------------
int HarvesterInstallationObject::getMaxHopperAmount() const
{
return m_maxHopperAmount.get();
}
// ----------------------------------------------------------------------
/**
* Add up the amounts of all the resources in the hopper
*/
float HarvesterInstallationObject::getCurrentHopperAmount() const
{
if (m_hopperAmount.get() >= 0)
return m_hopperAmount.get();
else
{
float total=0;
DynamicVariableList::NestedList l(getObjVars(),ObjVars::resource);
{
for (DynamicVariableList::NestedList::const_iterator i=l.begin(); i!=l.end(); ++i)
{
float var=0;
if (i.getValue(var))
total+=var;
}
}
return total;
}
}
// ----------------------------------------------------------------------
/**
* Return all the resource pools known to the current survey. If the
* survey is more than an hour old, refresh it.
*/
std::vector<ResourceTypeObject const *> const & HarvesterInstallationObject::getSurveyTypes()
{
if (!m_survey || ServerClock::getInstance().getGameTimeSeconds() - m_surveyTime > (60*60))
{
delete m_survey;
m_survey = NULL;
takeSurvey();
}
NOT_NULL(m_survey);
return *m_survey;
}
//----------------------------------------------------------------------
float HarvesterInstallationObject::alter(float time)
{
DEBUG_REPORT_LOG(true,("HarvesterInstallationObject::alter\n"));
float const result = InstallationObject::alter (time);
PROFILER_AUTO_BLOCK_DEFINE("HarvesterInstallationObject::alter");
if (isAuthoritative() && isActive())
harvest ();
InstallationSynchronizedUi * const syncUi = dynamic_cast<InstallationSynchronizedUi *>(getSynchronizedUi ());
if (syncUi)
{
syncUi->refresh();
}
addObjectToConcludeList();
return getNextAlterTime(result);
}
//----------------------------------------------------------------------
float HarvesterInstallationObject::getNextAlterTime(float baseAlterTime) const
{
if (baseAlterTime == AlterResult::cms_kill || baseAlterTime == AlterResult::cms_alterNextFrame) //lint !e777 // == with floats
return baseAlterTime;
float result = baseAlterTime;
InstallationSynchronizedUi const *syncUi = dynamic_cast<InstallationSynchronizedUi const *>(getSynchronizedUi());
//If GUI active update harvester more quickly
if (syncUi)
AlterResult::incorporateAlterResult(result, ConfigServerGame::getWatchedHarvesterAlterTime());
return result;
}
//----------------------------------------------------------------------
/**
* Return the contents of the hopper.
* @data Vector to store the contents (optional)
* @returns The sum of the resources in the hopper, i.e. total hopper
* space consumed.
*/
float HarvesterInstallationObject::getHopperContents(HopperContentsVector * data) const
{
if (m_hopperAmount.get() >= 0)
{
if (data && m_hopperAmount.get() != 0)
data->push_back(std::make_pair(m_hopperResource.get(), m_hopperAmount.get()));
return m_hopperAmount.get();
}
else
{
float total = 0;
const DynamicVariableList::NestedList l(getObjVars(),ObjVars::resource);
for (DynamicVariableList::NestedList::const_iterator pos=l.begin(); pos!=l.end(); ++pos)
{
float amount = 0;
if (pos.getValue(amount))
{
NetworkId networkIdValue(pos.getName());
if (data)
{
data->push_back (std::make_pair (networkIdValue, amount));
}
total += amount;
}
}
return total;
}
}
// ----------------------------------------------------------------------
/**
* Throws away the contents of the hopper.
*/
void HarvesterInstallationObject::discardAllHopperContents()
{
if (isAuthoritative())
{
removeObjVarItem(ObjVars::resource);
m_hopperAmount=0.0f;
m_hopperResource=NetworkId::cms_invalid;
}
else
{
//TODO: messages
}
}
//----------------------------------------------------------------------
void HarvesterInstallationObject::emptyHopper(const NetworkId & playerId, const NetworkId & resourceId, int amount, bool discard, uint8 sequenceId)
{
//TODO: what if not authoritative?
if (isAuthoritative())
{
CreatureObject * const player = dynamic_cast<CreatureObject *>(ServerWorld::findObjectByNetworkId (playerId));
if (!player)
{
WARNING (true, ("bad player"));
return;
}
bool success = false;
ServerObject * const inventory = (player && !discard) ? player->getInventory () : 0;
if (!discard && !inventory)
{
WARNING (true, ("no inventory"));
}
else
{
ResourceTypeObject const * const resType = ServerUniverse::getInstance().getResourceTypeById(resourceId);
if (!resType)
{
WARNING (true, ("bad resource specified"));
}
else
{
int amountToRemove=0;
if (amount < 0)
amountToRemove = static_cast<int>(getAmountOfResource(resourceId));
else
amountToRemove = std::min(amount,static_cast<int>(getAmountOfResource(resourceId)));
std::string crateTemplateName;
resType->getCrateTemplate(crateTemplateName);
ResourceContainerObject * crate = 0;
if (inventory)
{
crate = dynamic_cast<ResourceContainerObject*>(ServerWorld::createNewObject(crateTemplateName, *inventory, true));
if (!crate)
{
DEBUG_REPORT_LOG (!crate, ("error making crate %s. (Inventory was probably full.)\n", crateTemplateName.c_str()));
amountToRemove = 0;
}
}
if (crate)
{
amountToRemove = std::min (amountToRemove, crate->getMaxQuantity ());
if (!crate->addResource (CachedNetworkId (resourceId), amountToRemove, playerId))
{
WARNING (true, ("error adding resource to crate"));
amountToRemove = 0;
}
}
if (amountToRemove == 0)
DEBUG_REPORT_LOG (true, ("removed zero from harvester\n"));
else
addResource(resourceId, static_cast<float>(-amountToRemove));
success = true;
}
}
InstallationSynchronizedUi * const syncUi = dynamic_cast<InstallationSynchronizedUi *>(getSynchronizedUi ());
if (syncUi)
syncUi->refresh ();
{
MessageQueueGenericResponse * const resp = new MessageQueueGenericResponse (static_cast<int>(CM_clientResourceHarvesterEmptyHopper), success, sequenceId);
Controller *const controller = player->getController();
NOT_NULL(controller);
controller->appendMessage(static_cast<int>(CM_clientResourceHarvesterEmptyHopperResponse),0.0f,resp,
GameControllerMessageFlags::SEND |
GameControllerMessageFlags::RELIABLE |
GameControllerMessageFlags::DEST_AUTH_CLIENT);
}
return;
}
//----------------------------------------------------------------------
else
{
//TODO: multiserver messages
}
}
// ----------------------------------------------------------------------
/**
* Round the contents of the hopper to the nearest integer, discarding
* any fractional amounts.
*/
void HarvesterInstallationObject::roundHopperContents()
{
DEBUG_FATAL(!isAuthoritative(),("Programmer bug: roundHopperContents() is a helper function that should only be called on an authoritative object.\n"));
m_hopperAmount = static_cast<float>(static_cast<int>(m_hopperAmount.get()));
std::vector<std::string> itemsToRemove;
DynamicVariableList::NestedList resources(getObjVars(),ObjVars::resource);
for (DynamicVariableList::NestedList::const_iterator i=resources.begin(); i!=resources.end(); ++i)
{
float floatVal = 0;
if (i.getValue(floatVal))
{
int intVal = static_cast<int>(floatVal);
if (intVal == 0)
itemsToRemove.push_back(i.getNameWithPath());
else
{
IGNORE_RETURN(setObjVarItem(i.getNameWithPath(),static_cast<float>(intVal)));
}
}
}
for (std::vector<std::string>::const_iterator j=itemsToRemove.begin(); j!=itemsToRemove.end(); ++j)
removeObjVarItem(*j);
}
// ----------------------------------------------------------------------
void HarvesterInstallationObject::setCurrentExtractionRate(float currentExtractionRate)
{
if (isAuthoritative())
{
if (currentExtractionRate > m_maxExtractionRate.get())
{
DEBUG_WARNING(true,("Ignoring setCurrentExtractionRate(%f) because it was above maxExtractionRate %i.\n",
currentExtractionRate,m_maxExtractionRate.get()));
return;
}
if (m_currentExtractionRate.get() == currentExtractionRate)
return;
if (isActive())
{
//make sure we update the harvester contents with the old extraction rate
//before changing to the new extraction rate value
harvest();
deactivate();
m_currentExtractionRate = currentExtractionRate;
activate(NetworkId::cms_invalid);
}
else
{
m_currentExtractionRate = currentExtractionRate;
}
}
else
{
//TODO: messages
}
}
// ----------------------------------------------------------------------
/**
* Sets the maximum extraction rate.
* If the new max rate is less than the current rate, sets the current
* rate to the max rate.
* @todo Is that how we want to handle that case?
*/
void HarvesterInstallationObject::setMaxExtractionRate(int maxExtractionRate)
{
if (isAuthoritative())
{
m_maxExtractionRate=maxExtractionRate;
if (maxExtractionRate > m_currentExtractionRate.get())
{
DEBUG_REPORT_LOG(true,("Reducing current extraction rate to %i because max was changed.\n",maxExtractionRate));
setCurrentExtractionRate(static_cast<float>(maxExtractionRate));
}
}
else
{
//TODO: messages
}
}
// ----------------------------------------------------------------------
/**
* Sets the maximum hopper amount.
* If the new max hopper amount is greater than the amount in the hopper,
* it sets the max but does not discard any resources.
* @todo Is that how we want to handle that case?
*/
void HarvesterInstallationObject::setMaxHopperAmount(int maxHopperAmount)
{
if (isAuthoritative())
{
m_maxHopperAmount=maxHopperAmount;
}
else
{
//TODO: messages
}
}
// ----------------------------------------------------------------------
void HarvesterInstallationObject::handleCMessageTo (const MessageToPayload &message)
{
InstallationObject::handleCMessageTo (message);
}
// ----------------------------------------------------------------------
ResourceClassObject *HarvesterInstallationObject::getMasterClass() const
{
ResourceClassObject *obj = NULL;
const ServerHarvesterInstallationObjectTemplate *harvesterTemplate = dynamic_cast<const ServerHarvesterInstallationObjectTemplate*>(getObjectTemplate());
if (harvesterTemplate)
obj=ServerUniverse::getInstance().getResourceClassByName(harvesterTemplate->getMasterClassName());
if (!obj)
obj=ServerUniverse::getInstance().getResourceTreeRoot();
return obj;
}
// ----------------------------------------------------------------------
void HarvesterInstallationObject::sendResourceDataToClient(CreatureObject &clientObject)
{
ResourceDataVector dv;
getResourceData (dv);
if (!dv.empty ())
{
MessageQueueHarvesterResourceData * const newData = new MessageQueueHarvesterResourceData (getNetworkId (), dv);
CreatureController *controller = safe_cast<CreatureController*>(clientObject.getController());
controller->appendMessage(static_cast<int>(CM_clientResourceHarvesterResourceData), 0.0f, newData, GameControllerMessageFlags::SEND | GameControllerMessageFlags::RELIABLE | GameControllerMessageFlags::DEST_AUTH_CLIENT);
}
}
// ----------------------------------------------------------------------
void HarvesterInstallationObject::getAttributes(stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const
{
InstallationObject::getAttributes(data);
}
// ----------------------------------------------------------------------
/**
* Add (or subtract) resources to the hopper. In the case of subtraction,
* rounds a negative result to 0.
*/
void HarvesterInstallationObject::addResource(const NetworkId &resourceId, float amount)
{
if(isAuthoritative())
{
if (amount >= 0)
LOG("CustomerService", ("Harvest:adding %.2f of resource %s to harvester %s owned by %s", amount, resourceId.getValueString().c_str(), getNetworkId().getValueString().c_str(), PlayerObject::getAccountDescription(getOwnerId()).c_str()));
else
LOG("CustomerService", ("Harvest:removing %.2f of resource %s from harvester %s owned by %s", -amount, resourceId.getValueString().c_str(), getNetworkId().getValueString().c_str(), PlayerObject::getAccountDescription(getOwnerId()).c_str()));
if (m_hopperAmount.get() == 0 || m_hopperResource.get()==resourceId)
{
m_hopperResource = resourceId;
float newValue = m_hopperAmount.get() + amount;
m_hopperAmount = newValue > 0 ? newValue : 0;
}
else
{
if (m_hopperAmount.get() > 0) // splitting a single-resource harvester into a multi-resource harvester
{
std::string varName=std::string("resource.")+m_hopperResource.get().getValueString();
IGNORE_RETURN(setObjVarItem(varName,m_hopperAmount.get()));
m_hopperResource = NetworkId::cms_invalid;
m_hopperAmount = -1.0f; // flag that hopper amount is not meaningful and object variables should be used instead
}
std::string varName=std::string("resource.")+resourceId.getValueString(); // The name of the object variable is resource.XXX, where XXX is the networkId.
float oldValue = 0.0f;
IGNORE_RETURN(getObjVars().getItem(varName, oldValue));
float newValue = oldValue + amount;
if (newValue <= 0.0f)
{
removeObjVarItem (varName);
if (!getObjVars().hasItem(std::string("resource")))
m_hopperAmount = 0.0f; // back to being a single-resource harvester
}
else
IGNORE_RETURN(setObjVarItem(varName,newValue));
}
}
else
{
sendControllerMessageToAuthServer(CM_addResource, new MessageQueueGenericValueType<std::pair<NetworkId, float> >(std::make_pair(resourceId, amount)));
}
}
// ----------------------------------------------------------------------
/**
* Returns the amount of a particular resource in the hopper
*/
float HarvesterInstallationObject::getAmountOfResource(const NetworkId &resourceId) const
{
if (m_hopperAmount.get() >= 0)
{
if (resourceId == m_hopperResource.get())
return m_hopperAmount.get();
else
return 0;
}
else
{
// multiple resources in the hopper
float currentAmount = 0;
std::string objVarName(ObjVars::resource+'.'+resourceId.getValueString());
if (!getObjVars().getItem(objVarName, currentAmount))
return 0;
else
return currentAmount;
}
}
// ----------------------------------------------------------------------
bool HarvesterInstallationObject::isEmpty() const
{
return (getHopperContents(0) == 0.f);
}
// ----------------------------------------------------------------------
NetworkId const &HarvesterInstallationObject::getSelectedResourceTypeId() const
{
return m_resourceType.get();
}
// ----------------------------------------------------------------------
ResourcePoolObject const * HarvesterInstallationObject::getSelectedResourcePool() const
{
if (getSelectedResourceTypeId() == NetworkId::cms_invalid)
return NULL;
ResourceTypeObject const * const typeObject = ServerUniverse::getInstance().getResourceTypeById(getSelectedResourceTypeId());
if (typeObject)
{
return typeObject->getPoolForCurrentPlanet();
}
else
return NULL;
}
// ======================================================================
@@ -0,0 +1,109 @@
//========================================================================
//
// HarvesterInstallationObject.h
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#ifndef _INCLUDED_HarvesterInstallationObject_H
#define _INCLUDED_HarvesterInstallationObject_H
#include "serverGame/InstallationObject.h"
#include "sharedFoundation/NetworkIdArchive.h"
struct InstallationResourceData;
class ResourceClassObject;
class ResourceTypeObject;
class ResourcePoolObject;
class ServerHarvesterInstallationObjectTemplate;
/**
* A HarvesterInstallationObject is used to extract resources from the environment.
*/
class HarvesterInstallationObject : public InstallationObject
{
friend class HarvesterInstallationController;
public:
HarvesterInstallationObject(const ServerHarvesterInstallationObjectTemplate* newTemplate);
virtual ~HarvesterInstallationObject();
virtual Controller* createDefaultController(void);
void addMembersToPackages();
virtual float alter(float time);
virtual void getAttributes(stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const;
//simulation functions:
virtual void activate (const NetworkId &actorId);
virtual void deactivate ();
virtual void harvest ();
void selectResource (const NetworkId & resourceTypeId, const NetworkId &actor);
void discardAllHopperContents ();
void emptyHopper (const NetworkId & playerId, const NetworkId & resourceId, int amount, bool discard, uint8 sequenceId);
virtual void handleCMessageTo (const MessageToPayload &message);
//getters
typedef stdvector<InstallationResourceData>::fwd ResourceDataVector;
typedef std::pair<NetworkId, float> HopperContentElement;
typedef stdvector<HopperContentElement>::fwd HopperContentsVector;
float getHopperContents(HopperContentsVector * data=NULL) const;
void getResourceData(ResourceDataVector & data);
std::vector<ResourceTypeObject const *> const & getSurveyTypes();
int getMaxExtractionRate() const;
float getCurrentExtractionRate() const;
float getInstalledExtractionRate() const;
int getMaxHopperAmount() const;
float getCurrentHopperAmount() const;
float getAmountOfResource(const NetworkId &resourceId) const;
ResourceClassObject * getMasterClass() const;
void sendResourceDataToClient(CreatureObject &clientObject);
bool isEmpty() const;
NetworkId const & getSelectedResourceTypeId() const;
//setters
void setCurrentExtractionRate(float currentExtractionRate);
void setMaxExtractionRate(int maxExtractionRate);
void setMaxHopperAmount(int maxHopperAmount);
void addResource(const NetworkId &resourceId, float amount);
protected:
ServerSynchronizedUi * createSynchronizedUi ();
private:
void roundHopperContents();
float getNextAlterTime(float baseAlterTime) const;
void takeSurvey();
ResourcePoolObject const * getSelectedResourcePool() const;
private:
HarvesterInstallationObject();
HarvesterInstallationObject(const HarvesterInstallationObject& rhs);
HarvesterInstallationObject& operator=(const HarvesterInstallationObject& rhs);
private:
//BPM InstallationObject : BuildingObject // Begin persisted members.
Archive::AutoDeltaVariable<float> m_installedEfficiency; ///< For active harvesters, their resource collection efficiency
Archive::AutoDeltaVariable<NetworkId> m_resourceType; ///< The resource type this harvester is set to use
Archive::AutoDeltaVariable<int> m_maxExtractionRate;
Archive::AutoDeltaVariable<float> m_currentExtractionRate;
Archive::AutoDeltaVariable<int> m_maxHopperAmount;
Archive::AutoDeltaVariable<NetworkId> m_hopperResource;
Archive::AutoDeltaVariable<float> m_hopperAmount; // amount of resource in the hopper. 0=empty, >0 = hopper containes that quantity of m_hopperResource, <0 = use object variables instead (contains multiple resources)
//EPM
stdvector<ResourceTypeObject const *>::fwd * m_survey;
uint32 m_surveyTime;
/// Members yet to be implemented.
// inputResourceTypes
};
#endif
@@ -0,0 +1,503 @@
//========================================================================
//
// InstallationObject.cpp
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/InstallationObject.h"
#include "serverGame/Chat.h"
#include "serverGame/ContainerInterface.h"
#include "serverGame/CreatureObject.h"
#include "serverGame/InstallationController.h"
#include "serverGame/InstallationSynchronizedUi.h"
#include "serverGame/ObjectTracker.h"
#include "serverGame/PlanetObject.h"
#include "serverGame/PlayerObject.h"
#include "serverGame/ResourceContainerObject.h"
#include "serverGame/ResourcePoolObject.h"
#include "serverGame/ServerInstallationObjectTemplate.h"
#include "serverGame/ServerUniverse.h"
#include "serverNetworkMessages/MessageToPayload.h"
#include "serverUtility/ServerClock.h"
#include "sharedDebug/Profiler.h"
#include "sharedFoundation/ConstCharCrcLowerString.h"
#include "sharedFoundation/DynamicVariableList.h"
#include "sharedFoundation/GameControllerMessage.h"
#include "sharedGame/SharedStringIds.h"
#include "sharedLog/Log.h"
#include "sharedNetworkMessages/MessageQueueGenericResponse.h"
#include "sharedObject/NetworkIdManager.h"
#include "sharedObject/ObjectTemplateList.h"
#include "swgServerNetworkMessages/MessageQueueActivateInstallation.h"
#include "swgServerNetworkMessages/MessageQueueDeactivateInstallation.h"
#include "swgServerNetworkMessages/MessageQueueInstallationHarvest.h"
#include "swgServerNetworkMessages/MessageQueueResourceFinishHarvest.h"
#include "swgServerNetworkMessages/MessageQueueResourceSetInstalledEfficiency.h"
#include <stdio.h>
#include <vector>
//----------------------------------------------------------------------
static const std::string OBJVAR_ACCUMULATED_TIME("_installation.acclTime");
const SharedObjectTemplate * InstallationObject::m_defaultSharedTemplate = NULL;
namespace InstallationObjectNamespace
{
InstallationObject::AllInstallationsSet g_installationList;
}
using namespace InstallationObjectNamespace;
//----------------------------------------------------------------------
InstallationObject::InstallationObject(const ServerInstallationObjectTemplate* newTemplate) :
TangibleObject(newTemplate),
m_installationType(0),
m_tickCount(0.0f),
m_activated(false),
m_power(0),
m_powerRate(0),
m_activateStartTime(0)
{
addMembersToPackages();
IGNORE_RETURN(g_installationList.insert(this));
ObjectTracker::addInstallation();
}
//-----------------------------------------------------------------------
InstallationObject::~InstallationObject()
{
IGNORE_RETURN(g_installationList.erase(this));
ObjectTracker::removeInstallation();
}
//-----------------------------------------------------------------------
/**
* Returns a shared template if none was given for this object.
*
* @return the shared template
*/
const SharedObjectTemplate * InstallationObject::getDefaultSharedTemplate(void) const
{
static const ConstCharCrcLowerString templateName("object/installation/base/shared_installation_default.iff");
if (m_defaultSharedTemplate == NULL)
{
m_defaultSharedTemplate = safe_cast<const SharedObjectTemplate *>(
ObjectTemplateList::fetch(templateName));
WARNING_STRICT_FATAL(m_defaultSharedTemplate == NULL, ("Cannot create "
"default shared object template %s", templateName.getString()));
if (m_defaultSharedTemplate != NULL)
ExitChain::add (removeDefaultTemplate, "InstallationObject::removeDefaultTemplate");
}
return m_defaultSharedTemplate;
} // InstallationObject::getDefaultSharedTemplate
//-----------------------------------------------------------------------
/**
* Cleans up the default shared template.
*/
void InstallationObject::removeDefaultTemplate(void)
{
if (m_defaultSharedTemplate != NULL)
{
m_defaultSharedTemplate->releaseReference();
m_defaultSharedTemplate = NULL;
}
} // InstallationObject::removeDefaultTemplate
//-----------------------------------------------------------------------
/**
* Creates a default controller for this object.
*
* @return the object's controller
*/
Controller* InstallationObject::createDefaultController(void)
{
Controller* _controller = new InstallationController(this);
NOT_NULL(_controller);
setController(_controller);
return _controller;
}
//------------------------------------------------------------------------------------------
void InstallationObject::getByteStreamFromAutoVariable(const std::string & name, Archive::ByteStream & target) const
{
if(name == "powerValue")
{
m_power.pack(target);
}
else if(name == "powerRate")
{
m_powerRate.pack(target);
}
else
{
TangibleObject::getByteStreamFromAutoVariable(name, target);
}
}
//------------------------------------------------------------------------------------------
void InstallationObject::setAutoVariableFromByteStream(const std::string & name, const Archive::ByteStream & source)
{
Archive::ReadIterator ri(source);
if(name == "powerValue")
{
m_power.unpackDelta(ri);
}
else if(name == "powerRate")
{
m_powerRate.unpackDelta(ri);
}
else
{
TangibleObject::setAutoVariableFromByteStream(name, source);
}
addObjectToConcludeList();
}
// ----------------------------------------------------------------------
/**
* Activate an object as an installation. Assumes the object has already been
* placed in its intended location.
*/
void InstallationObject::activate(const NetworkId &actorId)
{
if (isAuthoritative())
{
const ServerObject *actor = safe_cast<const ServerObject*>(NetworkIdManager::getObjectById(actorId));
if (m_activated.get())
return;
float currentPower = getPower();
if (currentPower <= 0 && getPowerRate() > 0)
{
if (actor)
Chat::sendSystemMessage(*actor, SharedStringIds::harvester_no_power, Unicode::String());
return;
}
m_activated = true;
setCondition(ServerTangibleObjectTemplate::C_onOff);
setObjVarItem(OBJVAR_ACCUMULATED_TIME, 0.0f);
m_activateStartTime = static_cast<float>(ServerClock::getInstance().getGameTimeSeconds());
m_power = currentPower;
scheduleForAlter();
}
else
{
Controller *const controller = getController();
NOT_NULL(controller);
controller->appendMessage(static_cast<int>(CM_activateInstallation),0.0f,new MessageQueueActivateInstallation(),
GameControllerMessageFlags::SEND |
GameControllerMessageFlags::RELIABLE |
GameControllerMessageFlags::DEST_AUTH_SERVER);
}
}
// ----------------------------------------------------------------------
/**
* Deactivate an object as an installation.
*/
void InstallationObject::deactivate()
{
if (isAuthoritative())
{
if (!m_activated.get())
return;
// adjust power for time active
float currentTime = static_cast<float>(ServerClock::getInstance().getGameTimeSeconds());
setActivateStartTime(currentTime);
// turn the station off
m_tickCount = 0.0f;
m_activated = false;
clearCondition(ServerTangibleObjectTemplate::C_onOff);
scheduleForAlter();
}
else
{
Controller *const controller = getController();
NOT_NULL(controller);
controller->appendMessage(static_cast<int>(CM_deactivateInstallation),0.0f,new MessageQueueDeactivateInstallation(),
GameControllerMessageFlags::SEND |
GameControllerMessageFlags::RELIABLE |
GameControllerMessageFlags::DEST_AUTH_SERVER);
}
}
// ----------------------------------------------------------------------
void InstallationObject::harvest()
{
if (isAuthoritative())
{
}
else
{
Controller *const controller = getController();
NOT_NULL(controller);
controller->appendMessage(static_cast<int>(CM_installationHarvest),0.0f,new MessageQueueInstallationHarvest(),
GameControllerMessageFlags::SEND |
GameControllerMessageFlags::RELIABLE |
GameControllerMessageFlags::DEST_AUTH_SERVER);
}
}
// ----------------------------------------------------------------------
void InstallationObject::finishActivate(float installedEfficiency, float tickCount)
{
if (isAuthoritative())
{
if (m_activated.get())
{
m_tickCount = tickCount;
}
else
{
DEBUG_REPORT_LOG(true,("Got setInstalledEfficiency for installation %s, which was not activated.\n",getNetworkId().getValueString().c_str()));
}
}
else
{
MessageQueueResourceSetInstalledEfficiency* const message = new MessageQueueResourceSetInstalledEfficiency (installedEfficiency,tickCount);
Controller *const controller = getController();
NOT_NULL(controller);
controller->appendMessage(static_cast<int>(CM_resourceSetInstalledEfficiency),0.0f,message,
GameControllerMessageFlags::SEND |
GameControllerMessageFlags::RELIABLE |
GameControllerMessageFlags::DEST_AUTH_SERVER);
}
}
//----------------------------------------------------------------------
float InstallationObject::alter(float time)
{
PROFILER_AUTO_BLOCK_DEFINE("InstallationObject::alter");
return TangibleObject::alter(time);
}
// ----------------------------------------------------------------------
void InstallationObject::handleCMessageTo (const MessageToPayload &message)
{
if (message.getMethod() == "C++deactivate")
{
deactivate();
}
else if (message.getMethod() == "C++finishActivate")
{
float installedEfficiency;
float tickCount;
std::string packedData(message.getPackedDataVector().begin(), message.getPackedDataVector().end());
sscanf(
packedData.c_str(),
"%f %f",
&installedEfficiency,
&tickCount);
finishActivate(installedEfficiency,tickCount);
}
else
TangibleObject::handleCMessageTo(message);
}
// ----------------------------------------------------------------------
void InstallationObject::getAttributes(stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const
{
TangibleObject::getAttributes(data);
}
// ----------------------------------------------------------------------
/**
* Returns the amount of time the installation has been powered, based on the
* current time.
*
* @return the time powered, in secs
*/
float InstallationObject::getTimePowered(void) const
{
if (isActive())
{
float currentTime = static_cast<float>(ServerClock::getInstance().getGameTimeSeconds());
const_cast<InstallationObject*>(this)->setActivateStartTime(currentTime);
}
float accumulatedTime = 0.0f;
getObjVars().getItem(OBJVAR_ACCUMULATED_TIME, accumulatedTime);
return accumulatedTime;
} // InstallationObject::getTimePowered()
// ----------------------------------------------------------------------
/**
* Returns the time at which the installation will run out of power.
*
* @return the time in secs, -1 if it never runs out, and 0 if the installation
* is inactive
*/
float InstallationObject::getOutOfPowerTime(void) const
{
if (isActive() && m_powerRate.get() > 0)
return m_activateStartTime.get() + (m_power.get() / m_powerRate.get()) * 3600.0f;
else if (m_powerRate.get() <= 0)
return -1.0f;
return 0.0f;
} // InstallationObject::getOutOfPowerTime
// ----------------------------------------------------------------------
/**
* Sets the power consumption rate of the installation, in units/hour.
*
* @param rate the power rate
*/
void InstallationObject::setPowerRate(float rate)
{
// don't do anything if we're not really changing the rate
if (abs(rate - m_powerRate.get()) < 0.01f)
return;
if (isAuthoritative())
{
if (isActive())
{
// adjust the power for our current rate by changing the active time to our current time
setActivateStartTime(static_cast<float>(ServerClock::getInstance().getGameTimeSeconds()));
}
m_powerRate = rate;
}
}
// ----------------------------------------------------------------------
/**
* Changes the activation time to a given value. Will adjust the power available
* based on the difference between the current active time and the new one.
*
* @param time the new activation time for the installation
*/
void InstallationObject::setActivateStartTime(float time)
{
// if we're not active, there's no point in changing the time
if (!isActive())
return;
// see if we need to update the count of how long we've been powered
if (time > m_activateStartTime.get() &&
(m_power.get() > 0 || m_powerRate.get() <= 0))
{
// figure out how much power we used to get to the time value
float deltaTime = time - m_activateStartTime.get();
if (m_powerRate.get() > 0)
{
float deltaPower = (deltaTime / 3600.0f) * m_powerRate.get();
if (m_power.get() - deltaPower < 0.0f)
{
// we don't have enough power to make it to time; figure out
// when we ran out of power
deltaTime = (m_power.get() * 3600.0f / m_powerRate.get());
}
}
float accumulatedTime = 0.0f;
getObjVars().getItem(OBJVAR_ACCUMULATED_TIME, accumulatedTime);
setObjVarItem(OBJVAR_ACCUMULATED_TIME, accumulatedTime + deltaTime);
}
m_activateStartTime = time;
} // InstallationObject::setActivateStartTime
// ----------------------------------------------------------------------
/**
* Returns the amount of power the installation currently has left.
*/
float InstallationObject::getPower(void) const
{
float result = m_power.get();
if (result > 0.0f && m_powerRate.get() > 0.0f)
{
// return the power minus the amount that would be drained now
float powerUsed = (getTimePowered() / 3600.0f) * m_powerRate.get();
result = m_power.get() - powerUsed;
}
if (result <= 0.0f)
result = 0.0f;
return result;
} // InstallationObject::getPower
// ----------------------------------------------------------------------
/**
* Adds or removes power from the installation.
*
* @param delta amount to change the power by
*/
void InstallationObject::changePower(float delta)
{
if (isAuthoritative())
{
if (delta >= 0)
LOG("CustomerService", ("Power:adding %.2f power to installation %s owned by %s", delta, getNetworkId().getValueString().c_str(), PlayerObject::getAccountDescription(getOwnerId()).c_str()));
else
LOG("CustomerService", ("Power:removing %.2f power from installation %s owned by %s", -delta, getNetworkId().getValueString().c_str(), PlayerObject::getAccountDescription(getOwnerId()).c_str()));
float currentPower = getPower();
float newPower = currentPower + delta;
if (newPower > 0)
{
if (m_powerRate.get() > 0.0f)
newPower += (getTimePowered() / 3600.0f) * m_powerRate.get();
m_power = newPower;
}
else
{
// turn the installation off, and set the power so getPower will
// return exactly 0
if (isActive())
{
deactivate();
LOG("CustomerService", ("Power:shut down installation %s owned by %s due to 0 power", getNetworkId().getValueString().c_str(), PlayerObject::getAccountDescription(getOwnerId()).c_str()));
}
float powerUsed = (getTimePowered() / 3600.0f) * m_powerRate.get();
m_power = powerUsed;
}
}
else
{
WARNING(true, ("InstallationObject::changePower called for non-auth "
"object %s", getNetworkId().getValueString().c_str()));
}
} // InstallationObject::changePower
//-----------------------------------------------------------------------
const InstallationObject::AllInstallationsSet & InstallationObject::getAllInstallations()
{
return g_installationList;
}
// ======================================================================
@@ -0,0 +1,130 @@
//========================================================================
//
// InstallationObject.h
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#ifndef _INCLUDED_InstallationObject_H
#define _INCLUDED_InstallationObject_H
#include "serverGame/TangibleObject.h"
#include "sharedFoundation/NetworkIdArchive.h"
class MessageQueueResourceEmptyHopper;
class ServerInstallationObjectTemplate;
/**
* An InstallationObject typically represents a large un-enterable structure that performs the duties of an installation
* as described by the installation documentation.
*/
class InstallationObject : public TangibleObject
{
friend class InstallationController;
public:
InstallationObject(const ServerInstallationObjectTemplate* newTemplate);
virtual ~InstallationObject();
static void removeDefaultTemplate(void);
virtual Controller* createDefaultController(void);
void addMembersToPackages();
virtual float alter(float time);
virtual void getAttributes(stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const;
virtual void getByteStreamFromAutoVariable(const std::string & name, Archive::ByteStream & target) const;
virtual void setAutoVariableFromByteStream(const std::string & name, const Archive::ByteStream & source);
//simulation functions:
virtual void activate (const NetworkId &actorId);
virtual void finishActivate (float installedEfficiency, float tickCount);
virtual void deactivate ();
virtual void harvest ();
virtual void handleCMessageTo (const MessageToPayload &message);
//getters
bool isActive() const;
float getTickCount() const;
// power functions
float getPower(void) const;
void setPower(float power);
void changePower(float delta);
float getPowerRate(void) const;
void setPowerRate(float rate);
float getTimePowered(void) const;
float getOutOfPowerTime(void) const;
struct InstallationObjectPointerHash
{
size_t operator()(const InstallationObject * const ptr) const
{
return (reinterpret_cast<const size_t>(ptr) >> 4);
};
};
typedef stdhash_set<const InstallationObject *, InstallationObjectPointerHash>::fwd AllInstallationsSet;
static const AllInstallationsSet & getAllInstallations();
protected:
void setTickCount(float count);
void setActivateStartTime(float time);
virtual const SharedObjectTemplate * getDefaultSharedTemplate(void) const;
private:
InstallationObject();
InstallationObject(const InstallationObject& rhs);
InstallationObject& operator=(const InstallationObject& rhs);
private:
static const SharedObjectTemplate * m_defaultSharedTemplate; // template to use if no shared template is given
//BPM InstallationObject : TangibleObject // Begin persisted members.
Archive::AutoDeltaVariable<int32> m_installationType; ///< The type of installation (accessible by game scripts).
Archive::AutoDeltaVariable<float> m_tickCount; ///< For active installations, the tick count the last time they harvested resources
Archive::AutoDeltaVariable<bool> m_activated;
Archive::AutoDeltaVariable<float> m_power; // Amount of power the installation has
Archive::AutoDeltaVariable<float> m_powerRate; // Power used, in units/hour
Archive::AutoDeltaVariable<float> m_activateStartTime; // Time when the installation was turned on, from ServerClock::getGameTimeSeconds()
//EPM
/// Members yet to be implemented.
// permissionsList
};
inline bool InstallationObject::isActive() const
{
return m_activated.get();
}
inline float InstallationObject::getTickCount() const
{
return m_tickCount.get();
}
inline void InstallationObject::setTickCount(float count)
{
if (isAuthoritative())
m_tickCount = count;
}
inline void InstallationObject::setPower(float power)
{
changePower(power - getPower());
}
inline float InstallationObject::getPowerRate(void) const
{
return m_powerRate.get();
}
#endif
@@ -0,0 +1,945 @@
//========================================================================
//
// IntangibleObject.cpp
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/IntangibleObject.h"
#include "serverGame/Client.h"
#include "serverGame/ConfigServerGame.h"
#include "serverGame/ContainerInterface.h"
#include "serverGame/CreatureObject.h"
#include "serverGame/GameServer.h"
#include "serverGame/MessageToQueue.h"
#include "serverGame/ObjectTracker.h"
#include "serverGame/ObserveTracker.h"
#include "serverGame/Region.h"
#include "serverGame/RegionMaster.h"
#include "serverGame/ServerIntangibleObjectTemplate.h"
#include "serverGame/ServerUniverse.h"
#include "serverGame/ServerWorld.h"
#include "serverGame/ServerWorldIntangibleNotification.h"
#include "serverGame/TangibleObject.h"
#include "serverNetworkMessages/UpdateObjectOnPlanetMessage.h"
#include "serverScript/GameScriptObject.h"
#include "serverScript/ScriptParameters.h"
#include "serverUtility/ServerClock.h"
#include "sharedFoundation/Clock.h"
#include "sharedFoundation/ConstCharCrcLowerString.h"
#include "sharedFoundation/Crc.h"
#include "sharedGame/SharedObjectTemplate.h"
#include "sharedLog/Log.h"
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
#include "sharedObject/ObjectTemplateList.h"
#include "sharedTerrain/TerrainModificationHelper.h"
#include "sharedUtility/DataTable.h"
#include "sharedUtility/DataTableManager.h"
// ======================================================================
const SharedObjectTemplate * IntangibleObject::m_defaultSharedTemplate = NULL;
uint32 IntangibleObject::ms_lastFrame = 0;
uint32 IntangibleObject::ms_theaterTime = 0;
static const uint32 THEATER_DATATABLE_TAG = Crc::calculate("THEATER");
static const std::string THEATER_TEMPLATE("object/intangible/theater/base_theater.iff");
static const std::string THEATER_FLATTEN_LAYER("terrain/poi_small.lay");
static const std::string OBJVAR_THEATER_BASE("theater");
static const std::string OBJVAR_THEATER_CENTER(OBJVAR_THEATER_BASE + ".center");
static const std::string OBJVAR_THEATER_RADIUS(OBJVAR_THEATER_BASE + ".radius");
static const std::string OBJVAR_THEATER_PLAYER(OBJVAR_THEATER_BASE + ".player");
static const std::string OBJVAR_THEATER_OBJECTS(OBJVAR_THEATER_BASE + ".objects");
static const std::string OBJVAR_THEATER_NAME(OBJVAR_THEATER_BASE + ".name");
static const std::string OBJVAR_THEATER_FLATTEN(OBJVAR_THEATER_BASE + ".flatten");
// ======================================================================
IntangibleObject::IntangibleObject(const ServerIntangibleObjectTemplate* newTemplate) :
ServerObject(newTemplate, ServerWorldIntangibleNotification::getInstance()),
m_count(newTemplate->getCount()),
m_isTheater(false),
m_crcs(),
m_positions(),
m_headings(),
m_scripts(),
m_player(),
m_objects(),
m_center(),
m_radius(),
m_creator(),
m_theaterName()
#ifdef _DEBUG
, m_theaterCreationTime(0)
#endif
{
WARNING_STRICT_FATAL(!getSharedTemplate(), ("Shared template for %s is NULL", getTemplateName()));
addMembersToPackages();
ObjectTracker::addIntangible();
}
//-----------------------------------------------------------------------
IntangibleObject::~IntangibleObject()
{
ObjectTracker::removeIntangible();
} // IntangibleObject::~IntangibleObject
//-----------------------------------------------------------------------
/**
* Returns a shared template if none was given for this object.
*
* @return the shared template
*/
const SharedObjectTemplate * IntangibleObject::getDefaultSharedTemplate(void) const
{
static const ConstCharCrcLowerString templateName("object/intangible/base/shared_intangible_default.iff");
if (m_defaultSharedTemplate == NULL)
{
m_defaultSharedTemplate = safe_cast<const SharedObjectTemplate *>(
ObjectTemplateList::fetch(templateName));
WARNING_STRICT_FATAL(m_defaultSharedTemplate == NULL, ("Cannot create "
"default shared object template %s", templateName.getString()));
if (m_defaultSharedTemplate != NULL)
ExitChain::add (removeDefaultTemplate, "IntangibleObject::removeDefaultTemplate");
}
return m_defaultSharedTemplate;
} // IntangibleObject::getDefaultSharedTemplate
//-----------------------------------------------------------------------
/**
* Cleans up the default shared template.
*/
void IntangibleObject::removeDefaultTemplate(void)
{
if (m_defaultSharedTemplate != NULL)
{
m_defaultSharedTemplate->releaseReference();
m_defaultSharedTemplate = NULL;
}
} // IntangibleObject::removeDefaultTemplate
//-----------------------------------------------------------------------
void IntangibleObject::onLoadedFromDatabase()
{
ServerObject::onLoadedFromDatabase();
if (isAuthoritative())
{
if (getObjVars().hasItem(OBJVAR_THEATER_BASE))
{
Vector center;
float radius;
NetworkId player;
std::string name;
int flatten;
m_isTheater = true;
if (getObjVars().getItem(OBJVAR_THEATER_CENTER, center))
m_center = center;
if (getObjVars().getItem(OBJVAR_THEATER_RADIUS, radius))
m_radius = radius;
if (getObjVars().getItem(OBJVAR_THEATER_PLAYER, player))
m_player = CachedNetworkId(player);
if (getObjVars().getItem(OBJVAR_THEATER_NAME, name))
setTheaterName(name);
if (getObjVars().getItem(OBJVAR_THEATER_FLATTEN, flatten))
{
if (flatten != 0)
{
TerrainGenerator::Layer * layer = TerrainModificationHelper::importLayer(THEATER_FLATTEN_LAYER.c_str());
if (layer != NULL)
{
setLayer(layer);
}
}
}
std::vector<NetworkId> ids;
DynamicVariableList::NestedList objects(getObjVars(), OBJVAR_THEATER_OBJECTS);
for (DynamicVariableList::NestedList::const_iterator i = objects.begin();
i != objects.end(); ++i)
{
ids.clear();
if (i.getValue(ids))
{
for (std::vector<NetworkId>::const_iterator j = ids.begin();
j != ids.end(); ++j)
{
m_objects.push_back(CachedNetworkId(*j));
}
}
}
}
}
}
// ----------------------------------------------------------------------
void IntangibleObject::sendObjectSpecificBaselinesToClient(Client const &client) const
{
ServerObject::sendObjectSpecificBaselinesToClient(client);
if (getLayer() != NULL)
{
client.send(GenericValueTypeMessage<std::pair<NetworkId, bool> >(
"IsFlattenedTheaterMessage", std::make_pair(getNetworkId(), true)), true);
}
}
// ----------------------------------------------------------------------
float IntangibleObject::alter(float time)
{
size_t i;
float returnValue = ServerObject::alter(time);
if (isAuthoritative() && isTheater() && !isBeingDestroyed() && !isPlacing())
{
uint32 currentFrame = ServerClock::getInstance().getServerFrame();
if (currentFrame != ms_lastFrame)
{
ms_lastFrame = currentFrame;
ms_theaterTime = 0;
}
if (!m_crcs.empty() && m_crcs.size() > m_objects.size())
{
#ifdef _DEBUG
int objectsCreated = 0;
#endif
unsigned long totalTime = 0;
unsigned long startTime = Clock::timeMs();
const Vector myPos(getPosition_w());
size_t count = m_crcs.size();
for (i = m_objects.size(); i < count;)
{
if (ms_theaterTime + totalTime >= static_cast<unsigned long>
(ConfigServerGame::getTheaterCreationLimitMilliseconds()))
{
break;
}
Transform tr;
tr.setPosition_p(myPos+m_positions[i]);
ServerObject * newObject = ServerWorld::createNewObject(m_crcs[i], tr, 0, false);
if (newObject != NULL)
{
if (newObject->asTangibleObject() != NULL)
newObject->asTangibleObject()->setVisible(false);
newObject->addToWorld();
m_objects.push_back(CachedNetworkId(*newObject));
// set the object heading
if (i < m_headings.size())
{
newObject->yaw_o(m_headings[i] - newObject->getObjectFrameK_p().theta());
}
// attach the appropriate script to the object if needed
if (i < m_scripts.size() && !m_scripts[i].empty())
{
NOT_NULL(newObject->getScriptObject());
newObject->getScriptObject()->attachScript(m_scripts[i], true);
}
#ifdef _DEBUG
++objectsCreated;
#endif
}
else
{
m_objects.push_back(CachedNetworkId::cms_cachedInvalid);
WARNING(true, ("Theater object %s could not create object "
"from template crc %ul", getNetworkId().getValueString().c_str(),
m_crcs[i]));
}
++i;
unsigned long endTime = Clock::timeMs();
if (endTime >= startTime)
{
totalTime = endTime - startTime;
}
else
{
// time wrapped
totalTime = endTime + (ULONG_MAX - startTime);
}
}
ms_theaterTime += totalTime;
#ifdef _DEBUG
m_theaterCreationTime += totalTime;
DEBUG_LOG("Theater", ("Theater %s created %d objects, time = %lu\n",
getNetworkId().getValueString().c_str(), objectsCreated, totalTime));
#endif
if (i == count)
{
// we created all the objects
#ifdef _DEBUG
DEBUG_LOG("Theater", ("Theater %s total creation time = %lu\n",
getNetworkId().getValueString().c_str(), m_theaterCreationTime));
startTime = Clock::timeMs();
#endif
std::vector<ServerObject *> players;
Vector sphereCenter(m_center.get());
sphereCenter.y = findPosition_w().y;
ServerWorld::findPlayerCreaturesInRange(sphereCenter, m_radius.get() + 64.0f, players);
// make the objects visible
count = m_objects.size();
for (i = 0; i < count; ++i)
{
ServerObject * object = safe_cast<ServerObject *>(m_objects[i].getObject());
if (object != NULL && object->asTangibleObject() != NULL)
{
const ServerObjectTemplate * objTemplate = safe_cast<const ServerObjectTemplate *>(object->getObjectTemplate());
for (size_t j = 0; j < objTemplate->getVisibleFlagsCount(); ++j)
{
if (objTemplate->getVisibleFlags(j) == ServerObjectTemplate::VF_player)
{
object->asTangibleObject()->setVisible(true);
ObserveTracker::onObjectMadeVisibleTo(*object, players);
break;
}
}
}
}
// clear out data we don't need anymore
m_crcs.clear();
m_positions.clear();
m_headings.clear();
m_scripts.clear();
#ifdef _DEBUG
unsigned long endTime = Clock::timeMs();
if (endTime >= startTime)
{
totalTime = endTime - startTime;
}
else
{
// time wrapped
totalTime = endTime + (ULONG_MAX - startTime);
}
DEBUG_LOG("Theater", ("Theater %s make visible time = %lu\n",
getNetworkId().getValueString().c_str(), totalTime));
#endif
// tell scripts that we're done
NOT_NULL(getScriptObject());
ScriptParams params;
params.addParam(m_objects.get());
params.addParam(m_player.get());
params.addParam(m_creator.get());
IGNORE_RETURN(getScriptObject()->trigAllScripts(
Scripting::TRIG_THEATER_CREATED, params));
}
else
{
scheduleForAlter();
}
}
}
return returnValue;
}
//-----------------------------------------------------------------------
bool IntangibleObject::isVisibleOnClient (const Client & client) const
{
if (isTheater())
{
return getLayer() != NULL;
}
return true;
}
//------------------------------------------------------------------------------------------
/**
* Called when we are being destroyed. We will destroy any objects we've created.
*/
void IntangibleObject::onPermanentlyDestroyed()
{
if (isTheater())
{
DEBUG_LOG("Theater", ("IntangibleObject::onPermanentlyDestroyed destroying "
"theater %s", getNetworkId().getValueString().c_str()));
if (m_player.get() != CachedNetworkId::cms_invalid)
{
MessageToQueue::getInstance().sendMessageToC(m_player.get(),
"C++TheaterDestroyed", getNetworkId().getValueString(), 0,
false);
}
size_t count = m_objects.size();
for (size_t i = 0; i < count; ++i)
{
ServerObject * object = safe_cast<ServerObject *>(m_objects[i].getObject());
if (object != NULL)
object->permanentlyDestroy(DeleteReasons::Consumed);
}
if (!m_theaterName.get().empty())
ServerUniverse::getInstance().clearTheater(m_theaterName.get());
}
ServerObject::onPermanentlyDestroyed();
} // IntangibleObject::onPermanentlyDestroyed
//------------------------------------------------------------------------------------------
/**
* Persists this object in the database. Will also persist all the objects it
* is keeping track of.
*/
void IntangibleObject::persist()
{
if (isAuthoritative() && isTheater())
{
if (!m_crcs.empty() || m_objects.empty())
{
// we are not finished creating our objects, prevent persistance
WARNING(true, ("IntangibleObject::persist called before all objects created"));
return;
}
if (isPersisted())
return;
ServerObject::persist();
// We want to store our objects' ids in an objvar, but we can't store
// more than 1000 chars of data (which comes to about 47 network ids).
// So we split our objects into separate lists for storage
static const int MAX_IDS = 45;
std::vector<std::vector<NetworkId> > splitObjects;
splitObjects.reserve(1000 / MAX_IDS + 1);
int splitCount = MAX_IDS + 1;
// persist the objects in the theater
for (std::vector<CachedNetworkId>::const_iterator i = m_objects.begin();
i != m_objects.end(); ++i, ++splitCount)
{
if (splitCount > MAX_IDS)
{
splitObjects.push_back(std::vector<NetworkId>());
splitObjects.back().reserve(MAX_IDS);
splitCount = 0;
}
ServerObject * o = safe_cast<ServerObject *>((*i).getObject());
if (o != NULL)
{
o->persist();
splitObjects.back().push_back(*i);
}
}
// since we don't have a database table, store our persisted data in objvars
setObjVarItem(OBJVAR_THEATER_CENTER, m_center.get());
setObjVarItem(OBJVAR_THEATER_RADIUS, m_radius.get());
if (m_player.get() != CachedNetworkId::cms_cachedInvalid)
setObjVarItem(OBJVAR_THEATER_PLAYER, m_player.get());
setObjVarItem(OBJVAR_THEATER_NAME, m_theaterName.get());
if (getLayer() != NULL)
setObjVarItem(OBJVAR_THEATER_FLATTEN, 1);
char buffer[32];
int k = 0;
for (std::vector<std::vector<NetworkId> >::const_iterator j = splitObjects.begin();
j != splitObjects.end(); ++j, ++k)
{
int stored = snprintf(buffer, sizeof(buffer), "%s.%d", OBJVAR_THEATER_OBJECTS.c_str(), k);
if (static_cast<size_t>(stored) < sizeof(buffer))
setObjVarItem(buffer, *j);
else
{
WARNING_STRICT_FATAL(true, ("IntangibleObject::persist buffer "
"overflow, %d %d %u", k, stored, sizeof(buffer)));
}
}
}
else
ServerObject::persist();
} // IntangibleObject::persist
//------------------------------------------------------------------------------------------
bool IntangibleObject::onContainerAboutToTransfer(ServerObject * destination, ServerObject* transferer)
{
if (transferer && !destination)
{
//You cannot drop an intangible into the world.
DEBUG_REPORT_LOG(true, ("Player tried to drop an intangible object\n"));
return false;
}
return ServerObject::onContainerAboutToTransfer(destination, transferer);
}
//------------------------------------------------------------------------------------------
/**
* Sends a message to the Planet Server to update the position of the object.
*/
void IntangibleObject::updatePlanetServerInternal(const bool forceUpdate) const
{
// Don't send updates for contained intangibles, and only send when forced or moving
if ((forceUpdate || getPositionChanged()) && !ContainerInterface::getContainedByObject(*this))
{
Vector const &position = getPosition_p();
UpdateObjectOnPlanetMessage const msg(
getNetworkId(),
NetworkId::cms_invalid,
static_cast<int>(position.x),
static_cast<int>(position.y),
static_cast<int>(position.z),
0,
0,
false,
false,
static_cast<int>(getObjectType()),
0,
false,
getTemplateCrc(),
-1,
-1);
GameServer::getInstance().sendToPlanetServer(msg);
}
}
// ----------------------------------------------------------------------
/**
* Returns the approximate number of objects we can create per frame.
*
* @return the objects per frame
*/
int IntangibleObject::getObjectsCreatedPerFrame()
{
return static_cast<int>((ConfigServerGame::getTheaterCreationLimitMilliseconds() /
1000.0f) / 5.5f) + 1;
} // IntangibleObject::getObjectsCreatedPerFrame
//-----------------------------------------------------------------------
/**
* Returns the number of objects defined in a theater datatable.
*
* @param datatable the datatable containing the theater objects
*
* @return the theater's object count
*/
int IntangibleObject::getNumObjects(const std::string & datatable)
{
DataTable * dt = DataTableManager::getTable(datatable, true);
if (dt == NULL)
{
WARNING(true, ("IntangibleObject::getNumObjects could not open "
"datatable %s", datatable.c_str()));
return 0;
}
int rows = dt->getNumRows();
if (rows <= 0)
{
WARNING(true, ("IntangibleObject::getNumObjects datatable %s has no "
"rows", datatable.c_str()));
return 0;
}
int templateColumn = dt->findColumnNumber("template");
// if the 1st row's template is "THEATER", ignore it
if (static_cast<uint32>(dt->getIntValue(templateColumn, 0)) == THEATER_DATATABLE_TAG)
--rows;
return rows;
} // IntangibleObject::getNumObjects
//-----------------------------------------------------------------------
/**
* Determines the radius for the area taken up by a theater. Note that the radius
* is only determined by objects' positions, not size.
*
* @param datatable the datatable containing the theater objects
*
* @return the theater's radius
*/
float IntangibleObject::getRadius(const std::string & datatable)
{
DataTable * dt = DataTableManager::getTable(datatable, true);
if (dt == NULL)
{
WARNING(true, ("IntangibleObject::getRadius could not open "
"datatable %s", datatable.c_str()));
return 0;
}
int rows = dt->getNumRows();
if (rows <= 0)
{
WARNING(true, ("IntangibleObject::getRadius datatable %s has no "
"rows", datatable.c_str()));
return 0;
}
int templateColumn = dt->findColumnNumber("template");
int xColumn = dt->findColumnNumber("x");
int zColumn = dt->findColumnNumber("z");
float minx = FLT_MAX;
float maxx = -FLT_MIN;
float minz = FLT_MAX;
float maxz = -FLT_MIN;
for (int i = 0; i < rows; ++i)
{
if (i == 0)
{
// if the 1st row's template is "THEATER", ignore it
if (static_cast<uint32>(dt->getIntValue(templateColumn, i)) == THEATER_DATATABLE_TAG)
continue;
}
float x = dt->getFloatValue(xColumn, i);
float z = dt->getFloatValue(zColumn, i);
if (x < minx)
minx = x;
else if (x > maxx)
maxx = x;
if (z < minz)
minz = z;
else if (z > maxz)
maxz = z;
}
float xrad = (maxx - minx) / 2.0f;
float zrad = (maxz - minz) / 2.0f;
return sqrt(xrad * xrad + zrad * zrad);
} // IntangibleObject::getRadius
//-----------------------------------------------------------------------
/**
* Creates a new theater from a datatable.
*
* @param datatable the theater datatable
* @param postion the location of the theater
* @param script a script to be attached to the theater
* @param locationType how to create the theater
*
* @return the theater object
*/
IntangibleObject * IntangibleObject::spawnTheater(const std::string & datatable,
const Vector & position, const std::string & script, TheaterLocationType locationType)
{
DataTable * dt = DataTableManager::getTable(datatable, true);
if (dt == NULL)
{
WARNING(true, ("IntangibleObject::spawnTheater could not open "
"datatable %s", datatable.c_str()));
return NULL;
}
int rows = dt->getNumRows();
if (rows <= 0)
{
WARNING(true, ("IntangibleObject::spawnTheater datatable %s has no "
"rows", datatable.c_str()));
return NULL;
}
int templateColumn = dt->findColumnNumber("template");
int xColumn = dt->findColumnNumber("x");
int yColumn = dt->findColumnNumber("y");
int zColumn = dt->findColumnNumber("z");
int headingColumn = dt->findColumnNumber("heading");
int scriptColumn = dt->findColumnNumber("script");
std::vector<int32> objectCrcs;
std::vector<Vector> objectPositions;
std::vector<float> objectHeadings;
std::vector<std::string> objectScripts;
dt->getIntColumn(templateColumn, objectCrcs);
dt->getFloatColumn(headingColumn, objectHeadings);
bool skipFirstRow = false;
if (static_cast<uint32>(objectCrcs[0]) == THEATER_DATATABLE_TAG)
{
if (rows == 1)
{
WARNING(true, ("IntangibleObject::spawnTheater datatable %s has no "
"objects", datatable.c_str()));
return NULL;
}
skipFirstRow = true;
objectCrcs.erase(objectCrcs.begin());
objectHeadings.erase(objectHeadings.begin());
objectPositions.resize(rows-1);
objectScripts.resize(rows-1);
}
else
{
objectPositions.resize(rows);
objectScripts.resize(rows);
}
std::vector<float> tempPos;
int i, j;
int startIndex = skipFirstRow ? 1 : 0;
float minx = FLT_MAX;
float maxx = -FLT_MIN;
float minz = FLT_MAX;
float maxz = -FLT_MIN;
dt->getFloatColumn(xColumn, tempPos);
for (i = startIndex, j = 0; i < rows; ++i, ++j)
{
objectPositions[j].x = tempPos[i];
if (tempPos[i] < minx)
minx = tempPos[i];
else if (tempPos[i] > maxx)
maxx = tempPos[i];
}
dt->getFloatColumn(yColumn, tempPos);
for (i = startIndex, j = 0; i < rows; ++i, ++j)
objectPositions[j].y = tempPos[i];
dt->getFloatColumn(zColumn, tempPos);
for (i = startIndex, j = 0; i < rows; ++i, ++j)
{
objectPositions[j].z = tempPos[i];
if (tempPos[i] < minz)
minz = tempPos[i];
else if (tempPos[i] > maxz)
maxz = tempPos[i];
objectScripts[j] = dt->getStringValue(scriptColumn, i);
}
// Find out the area the theater will take up and use getGoodLocation
// to try and find somewhere where we can place the theater. Our search
// area is the size of the theater * 3.
float dx = maxx - minx;
float dz = maxz - minz;
float centerX = minx + dx / 2.0f + position.x;
float centerZ = minz + dz / 2.0f + position.z;
TerrainGenerator::Layer * layer = NULL;
if (locationType == TLT_flatten)
{
layer = TerrainModificationHelper::importLayer(THEATER_FLATTEN_LAYER.c_str());
if (layer == NULL)
{
WARNING (true, ("Layer %s not found for theater %s, using getGoodLocation "
"instead", THEATER_FLATTEN_LAYER.c_str(), datatable.c_str()));
locationType = TLT_getGoodLocation;
}
}
Vector goodLoc(centerX, 0, centerZ);
if (locationType == TLT_getGoodLocation)
{
goodLoc = ServerWorld::getGoodLocation(dx, dz, Vector(minx - dx + position.x,
0, minz - dz + position.z), Vector(maxx + dx + position.x, 0, maxz + dz + position.z),
false, false);
}
if (goodLoc.x == 0 && goodLoc.z == 0)
{
WARNING(true, ("IntangibleObject::spawnTheater could not find good location "
"of size %f %f around point %f %f", dx, dz, centerX, centerZ));
return 0;
}
// check the location region - don't spawn in cities or battlefields
std::vector<const Region *> regions;
RegionMaster::getRegionsAtPoint(ServerWorld::getSceneId(), goodLoc.x, goodLoc.z, regions);
for (std::vector<const Region *>::const_iterator iter = regions.begin();
iter != regions.end(); ++iter)
{
const Region * region = *iter;
if (region != NULL)
{
if (region->getPvp() == RegionNamespace::RP_pvpBattlefield ||
region->getPvp() == RegionNamespace::RP_pveBattlefield ||
region->getGeography() == RegionNamespace::RG_ocean ||
region->getGeography() == RegionNamespace::RG_underwater ||
region->getGeography() == RegionNamespace::RG_city)
{
WARNING(true, ("IntangibleObject::spawnTheater found good location "
"at %f %f in bad region %s", goodLoc.x, goodLoc.z,
Unicode::wideToNarrow(region->getName()).c_str()));
return 0;
}
}
}
DEBUG_LOG("Theater", ("IntangibleObject::spawnTheater found goodloc at %f %f",
goodLoc.x, goodLoc.z));
// create an object at the center of the theater that will be used to represent
// the entire theater
Transform tr;
tr.setPosition_p(goodLoc.x + position.x - centerX, 0, goodLoc.z + position.z - centerZ);
IntangibleObject * theater = safe_cast<IntangibleObject *>(ServerWorld::createNewObject(THEATER_TEMPLATE, tr, 0, false));
NOT_NULL(theater);
if (layer != NULL)
{
theater->setLayer(layer);
}
theater->setTheater();
theater->setObjects(objectCrcs, objectPositions, objectHeadings, objectScripts);
theater->addToWorld();
theater->scheduleForAlter();
if (!script.empty())
{
NOT_NULL(theater->getScriptObject());
theater->getScriptObject()->attachScript(script, true);
}
return theater;
} // IntangibleObject::spawnTheater
//-----------------------------------------------------------------------
/**
* Sets the data for the objects that will be created for the theater.
*
* @param crcs the object template crcs for the objects
* @param positions the positions where to create the objects, relative to
* our position
* @param headings the orientation of the objects
* @param scripts list scripts to be attached to the objects
*/
void IntangibleObject::setObjects(const std::vector<int32> & crcs,
const std::vector<Vector> & positions, const std::vector<float> & headings,
const std::vector<std::string> & scripts)
{
if (!isTheater())
return;
if (crcs.empty() || crcs.size() != positions.size())
return;
if (!headings.empty() && crcs.size() != headings.size())
return;
if (!scripts.empty() && crcs.size() != scripts.size())
return;
if (!isAuthoritative())
{
WARNING(true, ("IntangibleObject::setObjects called on non-authoritative "
"object"));
return;
}
float minx = FLT_MAX;
float maxx = -FLT_MIN;
float minz = FLT_MAX;
float maxz = -FLT_MIN;
size_t count = crcs.size();
for (size_t i = 0; i < count; ++i)
{
m_crcs.push_back(crcs[i]);
m_positions.push_back(positions[i]);
if (positions[i].x < minx)
minx = positions[i].x;
else if (positions[i].x > maxx)
maxx = positions[i].x;
if (positions[i].z < minz)
minz = positions[i].z;
else if (positions[i].z > maxz)
maxz = positions[i].z;
if (!headings.empty())
m_headings.push_back(convertDegreesToRadians(headings[i]));
if (!scripts.empty())
m_scripts.push_back(scripts[i]);
}
float xrad = (maxx - minx) / 2.0f;
float zrad = (maxz - minz) / 2.0f;
Vector mypos(getPosition_w());
m_center = Vector(minx + xrad + mypos.x, 0, minz + zrad + mypos.z);
m_radius = sqrt(xrad * xrad + zrad * zrad);
DEBUG_LOG("Theater", ("Theater %s center = %f %f, rad = %f",
getNetworkId().getValueString().c_str(), m_center.get().x,
m_center.get().z, m_radius.get()));
} // IntangibleObject::setObjects
//-----------------------------------------------------------------------
/**
* Sets the player this theater is created for.
*
* @param player the theater's player
*/
void IntangibleObject::setPlayer(const CreatureObject & player)
{
if (isTheater())
m_player = CachedNetworkId(player);
} // IntangibleObject::setPlayer
// ----------------------------------------------------------------------
/**
* Sets the name of this theater.
*
* @param name the theater's name
*
* @return true on success, false if there is already a theater with this name
*/
bool IntangibleObject::setTheaterName(const std::string & name)
{
if (!isAuthoritative())
return false;
if (!isTheater())
return false;
// don't allow renaming theaters
if (!m_theaterName.get().empty())
return false;
if (!name.empty())
{
const NetworkId & oldTheater = ServerUniverse::getInstance().findTheaterId(name);
if (oldTheater != NetworkId::cms_invalid)
return false;
ServerUniverse::getInstance().setTheater(name, getNetworkId());
}
m_theaterName = name;
return true;
} // IntangibleObject::setTheaterName
// ----------------------------------------------------------------------
void IntangibleObject::getAttributes(stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const
{
ServerObject::getAttributes(data);
}
// ----------------------------------------------------------------------
IntangibleObject *IntangibleObject::asIntangibleObject()
{
return this;
}
// ----------------------------------------------------------------------
IntangibleObject const *IntangibleObject::asIntangibleObject() const
{
return this;
}
// ======================================================================
@@ -0,0 +1,142 @@
//========================================================================
//
// IntangibleObject.h
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#ifndef INCLUDED_IntangibleObject_H
#define INCLUDED_IntangibleObject_H
//----------------------------------------------------------------------
#include "serverGame/ServerObject.h"
class ServerIntangibleObjectTemplate;
//----------------------------------------------------------------------
/**
* A IntangibleObject represents things that don't have a physical form in
* the game.
*/
class IntangibleObject : public ServerObject
{
public:
// NOTE: If you change these values, change the corresponding ones in base_class.java!
enum TheaterLocationType
{
TLT_none,
TLT_getGoodLocation,
TLT_flatten
};
public:
explicit IntangibleObject(const ServerIntangibleObjectTemplate* newTemplate);
virtual ~IntangibleObject();
virtual IntangibleObject *asIntangibleObject();
virtual IntangibleObject const *asIntangibleObject() const;
static void removeDefaultTemplate (void);
virtual float alter(float time);
virtual void onPermanentlyDestroyed();
virtual void persist();
virtual bool isVisibleOnClient (const Client & client) const;
virtual void getAttributes (stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const;
virtual bool onContainerAboutToTransfer(ServerObject * destination, ServerObject* transferer);
int getCount(void) const;
void setCount(int value);
void incrementCount(int delta);
// Theater stuff
static IntangibleObject * spawnTheater(const std::string & datatable, const Vector & position, const std::string & script, TheaterLocationType locationType);
static int getObjectsCreatedPerFrame();
static int getNumObjects(const std::string & datatable);
static float getRadius(const std::string & datatable);
void setTheater();
bool isTheater() const;
void setTheaterCreator(const NetworkId & creator);
bool setTheaterName(const std::string & name);
void setObjects(const std::vector<int32> & crcs, const std::vector<Vector> & positions, const std::vector<float> & headings, const std::vector<std::string> & scripts);
void setPlayer(const CreatureObject & player);
protected:
virtual void updatePlanetServerInternal(bool forceUpdate) const;
virtual const SharedObjectTemplate * getDefaultSharedTemplate(void) const;
virtual void onLoadedFromDatabase();
virtual void sendObjectSpecificBaselinesToClient(Client const &client) const;
private:
IntangibleObject();
IntangibleObject(const IntangibleObject& rhs);
IntangibleObject& operator=(const IntangibleObject& rhs);
private:
void addMembersToPackages();
private:
static const SharedObjectTemplate * m_defaultSharedTemplate; // template to use if no shared template is given
Archive::AutoDeltaVariable<int> m_count; // generic counter
// Theater stuff
Archive::AutoDeltaVariable<bool> m_isTheater; // flag that this is a theater
Archive::AutoDeltaVector<int32> m_crcs; // template crcs
Archive::AutoDeltaVector<Vector> m_positions; // object positions (relative to us)
Archive::AutoDeltaVector<float> m_headings; // object orientation
Archive::AutoDeltaVector<std::string> m_scripts; // scripts to be attached to the created objects
Archive::AutoDeltaVariable<CachedNetworkId> m_player; // the player the theater is created for
Archive::AutoDeltaVector<CachedNetworkId> m_objects; // objects created
Archive::AutoDeltaVariable<Vector> m_center; // center of the theater (not neccessarily our position)
Archive::AutoDeltaVariable<float> m_radius; // radius of the theater
Archive::AutoDeltaVariable<NetworkId> m_creator; // id of who created the theater
Archive::AutoDeltaVariable<std::string> m_theaterName;// the name of the theater
static uint32 ms_lastFrame;
static uint32 ms_theaterTime;
#ifdef _DEBUG
unsigned long m_theaterCreationTime;
#endif
};
//----------------------------------------------------------------------
inline int IntangibleObject::getCount(void) const
{
return m_count.get();
}
inline void IntangibleObject::setCount(int value)
{
m_count = value;
}
inline void IntangibleObject::incrementCount(int delta)
{
m_count = m_count.get() + delta;
}
inline void IntangibleObject::setTheater()
{
m_isTheater = true;
}
inline bool IntangibleObject::isTheater() const
{
return m_isTheater.get();
}
inline void IntangibleObject::setTheaterCreator(const NetworkId & creator)
{
m_creator = creator;
}
//----------------------------------------------------------------------
#endif // INCLUDED_IntangibleObject_H
@@ -0,0 +1,439 @@
// ======================================================================
//
// LineOfSightCache.cpp
//
// Copyright 2004 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/LineOfSightCache.h"
#include "serverGame/ConfigServerGame.h"
#include "serverGame/ContainerInterface.h"
#include "serverGame/CreatureObject.h"
#include "sharedCollision/BaseExtent.h"
#include "sharedCollision/CollisionProperty.h"
#include "sharedCollision/CollisionWorld.h"
#include "sharedCollision/ConfigSharedCollision.h"
#include "sharedDebug/Profiler.h"
#include "sharedFoundation/Clock.h"
#include "sharedObject/CellProperty.h"
#include "sharedObject/NetworkIdManager.h"
#include "sharedObject/Object.h"
#include "sharedObject/PortalProperty.h"
#include "sharedUtility/Location.h"
#include <queue>
// ======================================================================
namespace LineOfSightCacheNamespace
{
typedef std::pair<Object const *, Object const *> ObjectPair;
typedef std::pair<Object const *, Location> ObjectLocationPair;
typedef std::map<ObjectPair, bool> LineOfSightCacheMap;
typedef std::map<ObjectLocationPair, bool> LineOfSightLocationCacheMap;
typedef std::pair<ObjectPair, unsigned long> LineOfSightCacheExpireQueueEntry;
typedef std::pair<ObjectLocationPair, unsigned long> LineOfSightLocationCacheExpireQueueEntry;
typedef std::queue<LineOfSightCacheExpireQueueEntry> LineOfSightCacheExpireQueue;
typedef std::queue<LineOfSightLocationCacheExpireQueueEntry> LineOfSightLocationCacheExpireQueue;
LineOfSightCacheMap s_lineOfSightCacheMap;
LineOfSightCacheExpireQueue s_lineOfSightCacheExpireQueue;
LineOfSightLocationCacheMap s_lineOfSightLocationCacheMap;
LineOfSightLocationCacheExpireQueue s_lineOfSightLocationCacheExpireQueue;
}
using namespace LineOfSightCacheNamespace;
// ======================================================================
void LineOfSightCache::update()
{
unsigned long const frameStartTime = Clock::getFrameStartTimeMs();
while (!s_lineOfSightCacheExpireQueue.empty())
{
LineOfSightCacheExpireQueueEntry const &entry = s_lineOfSightCacheExpireQueue.front();
if (static_cast<int>(entry.second-frameStartTime) > 0)
break;
IGNORE_RETURN(s_lineOfSightCacheMap.erase(entry.first));
s_lineOfSightCacheExpireQueue.pop();
}
while (!s_lineOfSightLocationCacheExpireQueue.empty())
{
LineOfSightLocationCacheExpireQueueEntry const &entry = s_lineOfSightLocationCacheExpireQueue.front();
if (static_cast<int>(entry.second-frameStartTime) > 0)
break;
IGNORE_RETURN(s_lineOfSightLocationCacheMap.erase(entry.first));
s_lineOfSightLocationCacheExpireQueue.pop();
}
}
// ----------------------------------------------------------------------
bool LineOfSightCache::checkLOS(Object const &a, Object const &b)
{
PROFILER_AUTO_BLOCK_DEFINE("LineOfSightCache:checkLOS");
Object const *source = ContainerInterface::getFirstParentInWorld(a);
Object const *target = ContainerInterface::getFirstParentInWorld(b);
if (!source || !target)
return false;
if (source == target)
return true;
if (source > target)
std::swap(source, target);
std::pair<LineOfSightCacheMap::iterator, bool> result = s_lineOfSightCacheMap.insert(std::make_pair(ObjectPair(source, target), false));
if (result.second)
{
PROFILER_AUTO_BLOCK_DEFINE("LineOfSightCache:checkLOS (uncached)");
s_lineOfSightCacheExpireQueue.push(
LineOfSightCacheExpireQueueEntry(
ObjectPair(source, target),
Clock::getFrameStartTimeMs() + ConfigServerGame::getLineOfSightCacheDurationMs()));
CellProperty const * const sourceCell = source->getParentCell();
CellProperty const * const targetCell = target->getParentCell();
// if source and target are in the same cell in a player structure, skip LOS check;
// this is similar to the skip collision check if the object is in a player structure
// (see CollisionProperty::canCollideWith)
if (sourceCell && (sourceCell == targetCell) && (sourceCell != CellProperty::getWorldCellProperty()))
{
PortalProperty const * portalProperty = sourceCell->getPortalProperty();
if (portalProperty)
{
IsPlayerHouseHook hook = ConfigSharedCollision::getIsPlayerHouseHook();
if (hook && hook(&portalProperty->getOwner()))
{
(*result.first).second = true; // line of sight is clear
return true;
}
}
}
Vector const sourcePos(source->getPosition_c());
Vector const targetPos(target->getPosition_c());
float const sourceHeight = sourcePos.y + ConfigServerGame::getLineOfSightCacheMinHeight();
float const targetHeight = targetPos.y + ConfigServerGame::getLineOfSightCacheMinHeight();
CollisionProperty const * const sourceCollision = NON_NULL(source->getCollisionProperty());
CollisionProperty const * const targetCollision = NON_NULL(target->getCollisionProperty());
if (!sourceCollision->isInCollisionWorld())
sourceCollision->updateExtents();
if (!targetCollision->isInCollisionWorld())
targetCollision->updateExtents();
BaseExtent const * const sourceExtent = sourceCollision ? sourceCollision->getExtent_p() : 0;
BaseExtent const * const targetExtent = targetCollision ? targetCollision->getExtent_p() : 0;
ServerObject const *sourceServerObject = source->asServerObject();
ServerObject const *targetServerObject = target->asServerObject();
CreatureObject const *sourceCreatureObject = (sourceServerObject) ? sourceServerObject->asCreatureObject() : 0;
CreatureObject const *targetCreatureObject = (targetServerObject) ? targetServerObject->asCreatureObject() : 0;
Postures::Enumerator sourcePosture = (sourceCreatureObject) ? sourceCreatureObject->getPosture() : Postures::Invalid;
Postures::Enumerator targetPosture = (targetCreatureObject) ? targetCreatureObject->getPosture() : Postures::Invalid;
Vector sourceTop = sourcePos;
Vector targetTop = targetPos;
// first process special handling for creature objects
if (sourceCreatureObject)
{
if (sourceExtent)
{
sourceTop = sourceExtent->getCenter();
if (sourceCreatureObject->isPlayerControlled())
{
if (sourcePosture == Postures::Upright)
sourceTop.y += sourceExtent->getRadius() * ConfigSharedCollision::getLosUprightScale();
else if (sourcePosture == Postures::Prone || sourcePosture == Postures::LyingDown || sourcePosture == Postures::KnockedDown)
sourceTop.y -= sourceExtent->getRadius() * ConfigSharedCollision::getLosProneScale();
else if (sourcePosture == Postures::Crouched || sourcePosture == Postures::Sitting)
sourceTop.y += sourceExtent->getRadius() * ConfigSharedCollision::getLosUprightScale() * 0.5f;
}
else
{
// we currently don't have a good algorithm for a LOS point on non-player creatures - use extent center
}
}
}
else
{
if (sourceExtent)
{
// if the extent exists, use the top of it
sourceTop = sourceExtent->getCenter();
sourceTop.y += sourceExtent->getRadius();
}
else
{
const Sphere sourceSphere = sourceCollision ? sourceCollision->getBoundingSphere_w() : Sphere(sourceTop, 0.0f);
if (sourceSphere.getRadius() != 0.0f)
{
// we move the point up to the top of the collision sphere
sourceTop = source->getTransform_p2w().rotateTranslate_p2l(sourceSphere.getCenter());
sourceTop.y += sourceSphere.getRadius();
}
}
}
if (targetCreatureObject)
{
if (targetExtent)
{
targetTop = targetExtent->getCenter();
if (targetCreatureObject->isPlayerControlled())
{
if (targetPosture == Postures::Upright)
targetTop.y += targetExtent->getRadius() * ConfigSharedCollision::getLosUprightScale();
else if (targetPosture == Postures::Prone || targetPosture == Postures::LyingDown || targetPosture == Postures::KnockedDown)
targetTop.y -= targetExtent->getRadius() * ConfigSharedCollision::getLosProneScale();
else if (targetPosture == Postures::Crouched || targetPosture == Postures::Sitting)
targetTop.y += targetExtent->getRadius() * ConfigSharedCollision::getLosUprightScale() * 0.5f;
}
else
{
// we currently don't have a good algorithm for a LOS point on non-player creatures - use extent center
}
}
}
else
{
if (targetExtent)
{
// if the extent exists, use the top of it
targetTop = targetExtent->getCenter();
targetTop.y += targetExtent->getRadius();
}
else
{
const Sphere targetSphere = targetCollision ? targetCollision->getBoundingSphere_w() : Sphere(targetTop, 0.0f);
if (targetSphere.getRadius() != 0.0f)
{
// we move the point up to the top of the collision sphere
targetTop = target->getTransform_p2w().rotateTranslate_p2l(targetSphere.getCenter());
targetTop.y += targetSphere.getRadius();
}
}
}
if (sourceTop.y < sourceHeight)
sourceTop.y = sourceHeight;
if (targetTop.y < targetHeight)
targetTop.y = targetHeight;
// Check both directions for obstructions
QueryInteractionResult qirResult = QIR_None;
float outHitTime = 0.f;
Object const *outHitObject = 0;
qirResult = CollisionWorld::queryInteraction(
sourceCell, sourceTop,
targetCell, targetTop,
source,
!ConfigSharedCollision::getIgnoreTerrainLos(),
ConfigSharedCollision::getGenerateTerrainLos(),
ConfigSharedCollision::getTerrainLOSMinDistance(),
ConfigSharedCollision::getTerrainLOSMaxDistance(),
outHitTime,
outHitObject);
if (qirResult == QIR_None || outHitObject == target)
{
// We don't need to do terrain LOS in the opposite direction if the
// initial terrain LOS check was done using all possible terrain
// between the 2 points (generating any missing terrain in the process).
qirResult = CollisionWorld::queryInteraction(
targetCell, targetTop,
sourceCell, sourceTop,
target,
(!ConfigSharedCollision::getIgnoreTerrainLos() && !ConfigSharedCollision::getGenerateTerrainLos()),
false,
ConfigSharedCollision::getTerrainLOSMinDistance(),
ConfigSharedCollision::getTerrainLOSMaxDistance(),
outHitTime,
outHitObject);
if (qirResult == QIR_None || outHitObject == source)
(*result.first).second = true; // line of sight is clear
}
}
// return the (now) cached result
return (*result.first).second;
}
// ----------------------------------------------------------------------
bool LineOfSightCache::checkLOS(Object const &a, Location const &b)
{
PROFILER_AUTO_BLOCK_DEFINE("LineOfSightLocationCache:checkLOS");
Object const *source = ContainerInterface::getFirstParentInWorld(a);
if (!source)
return false;
// round the target location
float roundValue = ConfigServerGame::getLineOfSightLocationRoundValue();
Vector targetPos(b.getCoordinates());
targetPos.x -= static_cast<float>(fmod(static_cast<float>(targetPos.x), roundValue));
targetPos.y -= static_cast<float>(fmod(static_cast<float>(targetPos.y), roundValue));
targetPos.z -= static_cast<float>(fmod(static_cast<float>(targetPos.z), roundValue));
Location target(targetPos, b.getCell(), b.getSceneIdCrc());
std::pair<LineOfSightLocationCacheMap::iterator, bool> result = s_lineOfSightLocationCacheMap.insert(std::make_pair(ObjectLocationPair(source, target), false));
if (result.second)
{
PROFILER_AUTO_BLOCK_DEFINE("LineOfSightLocationCache:checkLOS (uncached)");
s_lineOfSightLocationCacheExpireQueue.push(
LineOfSightLocationCacheExpireQueueEntry(
ObjectLocationPair(source, target),
Clock::getFrameStartTimeMs() + ConfigServerGame::getLineOfSightCacheDurationMs()));
CellProperty const * const sourceCell = source->getParentCell();
CellProperty const * targetCell = NULL;
if (b.getCell() != NetworkId::cms_invalid)
{
Object const * cellObject = NetworkIdManager::getObjectById(b.getCell());
if (cellObject != NULL)
targetCell = ContainerInterface::getCell(*cellObject);
}
if (targetCell == NULL)
targetCell = CellProperty::getWorldCellProperty();
// if source and target are in the same cell in a player structure, skip LOS check;
// this is similar to the skip collision check if the object is in a player structure
// (see CollisionProperty::canCollideWith)
if (sourceCell && (sourceCell == targetCell) && (sourceCell != CellProperty::getWorldCellProperty()))
{
PortalProperty const * portalProperty = sourceCell->getPortalProperty();
if (portalProperty)
{
IsPlayerHouseHook hook = ConfigSharedCollision::getIsPlayerHouseHook();
if (hook && hook(&portalProperty->getOwner()))
{
(*result.first).second = true; // line of sight is clear
return true;
}
}
}
Vector const sourcePos(source->getPosition_c());
float const sourceHeight = sourcePos.y + ConfigServerGame::getLineOfSightCacheMinHeight();
CollisionProperty const * const sourceCollision = NON_NULL(source->getCollisionProperty());
if (!sourceCollision->isInCollisionWorld())
sourceCollision->updateExtents();
BaseExtent const * const sourceExtent = sourceCollision ? sourceCollision->getExtent_p() : 0;
ServerObject const *sourceServerObject = source->asServerObject();
CreatureObject const *sourceCreatureObject = (sourceServerObject) ? sourceServerObject->asCreatureObject() : 0;
Postures::Enumerator sourcePosture = (sourceCreatureObject) ? sourceCreatureObject->getPosture() : Postures::Invalid;
Vector sourceTop(sourcePos);
// first process special handling for creature objects
if (sourceCreatureObject)
{
if (sourceExtent)
{
sourceTop = sourceExtent->getCenter();
if (sourceCreatureObject->isPlayerControlled())
{
if (sourcePosture == Postures::Upright)
sourceTop.y += sourceExtent->getRadius() * ConfigSharedCollision::getLosUprightScale();
else if (sourcePosture == Postures::Prone || sourcePosture == Postures::LyingDown || sourcePosture == Postures::KnockedDown)
sourceTop.y -= sourceExtent->getRadius() * ConfigSharedCollision::getLosProneScale();
else if (sourcePosture == Postures::Crouched || sourcePosture == Postures::Sitting)
sourceTop.y += sourceExtent->getRadius() * ConfigSharedCollision::getLosUprightScale() * 0.5f;
}
else
{
// we currently don't have a good algorithm for a LOS point on non-player creatures - use extent center
}
}
}
else
{
if (sourceExtent)
{
// if the extent exists, use the top of it
sourceTop = sourceExtent->getCenter();
sourceTop.y += sourceExtent->getRadius();
}
else
{
const Sphere sourceSphere = sourceCollision ? sourceCollision->getBoundingSphere_w() : Sphere(sourceTop, 0.0f);
if (sourceSphere.getRadius() != 0.0f)
{
// we move the point up to the top of the collision sphere
sourceTop = source->getTransform_p2w().rotateTranslate_p2l(sourceSphere.getCenter());
sourceTop.y += sourceSphere.getRadius();
}
}
}
if (sourceTop.y < sourceHeight)
sourceTop.y = sourceHeight;
// Check both directions for obstructions
QueryInteractionResult qirResult = QIR_None;
float outHitTime = 0.f;
Object const *outHitObject = 0;
qirResult = CollisionWorld::queryInteraction(
sourceCell, sourceTop,
targetCell, b.getCoordinates(),
source,
!ConfigSharedCollision::getIgnoreTerrainLos(),
ConfigSharedCollision::getGenerateTerrainLos(),
ConfigSharedCollision::getTerrainLOSMinDistance(),
ConfigSharedCollision::getTerrainLOSMaxDistance(),
outHitTime,
outHitObject);
if (qirResult == QIR_None)
{
// We don't need to do terrain LOS in the opposite direction if the
// initial terrain LOS check was done using all possible terrain
// between the 2 points (generating any missing terrain in the process).
qirResult = CollisionWorld::queryInteraction(
targetCell, b.getCoordinates(),
sourceCell, sourceTop,
NULL,
(!ConfigSharedCollision::getIgnoreTerrainLos() && !ConfigSharedCollision::getGenerateTerrainLos()),
false,
ConfigSharedCollision::getTerrainLOSMinDistance(),
ConfigSharedCollision::getTerrainLOSMaxDistance(),
outHitTime,
outHitObject);
if (qirResult == QIR_None || outHitObject == source)
(*result.first).second = true; // line of sight is clear
}
}
// return the (now) cached result
return (*result.first).second;
}
// ======================================================================
@@ -0,0 +1,30 @@
// ======================================================================
//
// LineOfSightCache.h
//
// Copyright 2004 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_LineOfSightCache_H
#define INCLUDED_LineOfSightCache_H
// ======================================================================
class Location;
class Object;
// ======================================================================
class LineOfSightCache
{
public:
static void update();
static bool checkLOS(Object const &a, Object const &b);
static bool checkLOS(Object const &a, Location const &b);
};
// ======================================================================
#endif // INCLUDED_LineOfSightCache_H
@@ -0,0 +1,104 @@
//========================================================================
//
// ManufactureInstallationObject.h
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#ifndef _INCLUDED_ManufactureInstallationObject_H
#define _INCLUDED_ManufactureInstallationObject_H
#include "serverGame/InstallationObject.h"
#include "sharedFoundation/NetworkIdArchive.h"
#include "sharedFoundation/StationId.h"
class FactoryObject;
class ManufactureSchematicObject;
class ServerManufactureInstallationObjectTemplate;
/**
* A ManufactureInstallationObject is used to create new objects from a
* manufacture schematic.
*/
class ManufactureInstallationObject : public InstallationObject
{
friend class InstallationController;
public:
ManufactureInstallationObject(const ServerManufactureInstallationObjectTemplate* newTemplate);
virtual ~ManufactureInstallationObject();
virtual Controller* createDefaultController();
void addMembersToPackages();
virtual void getAttributes(AttributeVector &data) const;
virtual void onContainerChildLostItem(ServerObject * destination, ServerObject& item, ServerObject* source, ServerObject* transferer);
virtual void onContainerChildGainItem(ServerObject& item, ServerObject* source, ServerObject* transferer);
virtual float alter(float time);
uint32 getValidSchematicTypes() const;
int getNumNewItems() const;
const std::string & getOwnerName() const;
StationId getOwnerStationId() const;
virtual void setOwnerId(const NetworkId &id);
ServerObject * getInputHopper() const;
ServerObject * getOutputHopper() const;
bool addSchematic(ManufactureSchematicObject & schematic, ServerObject * transferer);
virtual bool onContainerAboutToLoseItem(ServerObject * destination, ServerObject& item, ServerObject* transferer);
ManufactureSchematicObject * getSchematic() const;
float getTimePerObject() const;
//simulation functions:
virtual void activate (const NetworkId &actorId);
virtual void deactivate ();
virtual void harvest ();
bool createObject (bool testOnly = false);
protected:
virtual void initializeFirstTimeObject();
virtual void endBaselines();
void setTickCount(float count);
private:
ManufactureInstallationObject();
ManufactureInstallationObject(const ManufactureInstallationObject& rhs);
ManufactureInstallationObject& operator=(const ManufactureInstallationObject& rhs);
private:
class TaskManufactureObject;
friend class TaskManufactureObject;
typedef stdvector<std::pair<CachedNetworkId, int> >::fwd IngredientVector;
void restoreIngredients(IngredientVector const &ingredients);
void destroyIngredients(IngredientVector const &ingredients);
bool transferCraftedIngredientToSchematic(ServerObject & inputHopper, ManufactureSchematicObject & schematic, const NetworkId & craftedId, int ingredientCount, IngredientVector &ingredients);
const NetworkId & transferTemplateIngredientToSchematic(ServerObject & inputHopper, ManufactureSchematicObject & schematic, const ObjectTemplate & componentTemplate, IngredientVector &ingredients);
const NetworkId & transferResourceTypeToSchematic(ServerObject & inputHopper, ManufactureSchematicObject & schematic, const NetworkId & resourceTypeId, int resourceCount);
FactoryObject * getCurrentCrate(const ManufactureSchematicObject & contents);
FactoryObject * makeNewCrate(const ManufactureSchematicObject & contents);
private:
CachedNetworkId m_currentCrate; // crate we are stuffing objects into
};
inline void ManufactureInstallationObject::setTickCount(float count)
{
InstallationObject::setTickCount(count);
}
#endif // _INCLUDED_ManufactureInstallationObject_H
@@ -0,0 +1,53 @@
//========================================================================
//
// ManufactureObjectInterface.h
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#ifndef INCLUDED_ManufactureObjectInterface_H
#define INCLUDED_ManufactureObjectInterface_H
#include "serverGame/ServerIntangibleObjectTemplate.h"
namespace Crafting
{
struct IngredientSlot;
}
//========================================================================
/**
* Pure abstract class that must be implemented by objects that can be used to
* create new crafted items
*/
class ManufactureObjectInterface
{
public:
typedef std::map<StringId, float> AttribMap;
typedef std::vector<StringId> StringIdList;
virtual uint32 getDraftSchematic() const = 0;
virtual bool getSlot(int index, Crafting::IngredientSlot & data, bool flag) const = 0;
virtual int getSlotsCount() const = 0;
virtual const AttribMap & getAttributes() const = 0;
virtual void setAttribute(const ServerIntangibleObjectTemplate::SchematicAttribute & attribute) = 0;
virtual void setAttribute(const StringId & name, float value) = 0;
virtual const AttribMap & getResourceMaxAttributes() const = 0;
virtual void setResourceMaxAttribute(const StringId & name, float value) = 0;
virtual const StringIdList & getExperimentAttributeNames() const = 0;
virtual void setExperimentAttribute(const StringId & name, float value) = 0;
virtual void getAllExperimentAttributeValues(const StringId & name, float & value, float & minValue, float & maxValue, float & resourceMaxValue) const = 0;
virtual void setExperimentAttributeLimits(const StringId & name, float minValue, float maxValue, float resourceMaxValue) = 0;
virtual bool isMakingObject(void) const = 0;
virtual const NetworkId & getDerivedNetworkId() const = 0;
};
//========================================================================
#endif // INCLUDED_ManufactureObjectInterface_H
@@ -0,0 +1,249 @@
//========================================================================
//
// ManufactureSchematicObject.h
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#ifndef INCLUDED_ManufactureSchematicObject_H
#define INCLUDED_ManufactureSchematicObject_H
#include "Archive/AutoDeltaByteStream.h"
#include "Archive/AutoDeltaMap.h"
#include "serverGame/IntangibleObject.h"
#include "serverGame/ManufactureObjectInterface.h"
#include "serverGame/ServerIntangibleObjectTemplate.h"
class CreatureObject;
class DraftSchematicObject;
class FactoryObject;
class ManufactureSchematicSynchronizedUi;
class ResourceContainerObject;
class ServerManufactureSchematicObjectTemplate;
class TangibleObject;
namespace Crafting
{
struct CustomInfo;
struct IngredientSlot;
class SimpleIngredient;
class ComponentIngredient;
}
//========================================================================
/**
* A ManufactureSchematicObject is used to create new objects.
*/
class ManufactureSchematicObject : public IntangibleObject, public ManufactureObjectInterface
{
public:
typedef std::map<StringId, float> AttribMap;
typedef std::vector<StringId> StringIdList;
explicit ManufactureSchematicObject(const ServerManufactureSchematicObjectTemplate* newTemplate);
virtual ~ManufactureSchematicObject();
virtual ManufactureSchematicObject * asManufactureSchematicObject();
virtual ManufactureSchematicObject const * asManufactureSchematicObject() const;
static void removeDefaultTemplate ();
virtual void kill ();
void init (const DraftSchematicObject & schematic, const CachedNetworkId & creator);
void reset ();
void addMembersToPackages ();
virtual int getVolume () const;
virtual void getAttributes (AttributeVector &data) const;
ServerIntangibleObjectTemplate::CraftingType getCategory() const;
virtual uint32 getDraftSchematic() const;
const NetworkId & getCreatorId() const;
NetworkId getOriginalId() const;
bool mustDestroyIngredients() const;
bool getSlot(const StringId & name, Crafting::IngredientSlot & data);
virtual bool getSlot(int index, Crafting::IngredientSlot & data, bool flag) const;
virtual int getSlotsCount() const;
void setSlotType(const StringId & name, int type);
void setSlotOption(const StringId & name, int option);
void setSlotIndex(const StringId & name, int index);
void modifySlotComplexity(const StringId & name, float complexityDelta);
void addSlotResource(const StringId & name, const NetworkId & resourceId, int count, const NetworkId & sourceId);
void addSlotComponent(const StringId & name, const TangibleObject & component, ServerIntangibleObjectTemplate::IngredientType ingredientType);
TangibleObject * getComponent(const Crafting::ComponentIngredient & info) const;
void setSlotSources(int slotIndex, const std::vector<std::pair<NetworkId, int> > & sources);
void clearSlot(const StringId & name);
void clearSlot(int index);
void clearSlotSources();
void clearSlotSources(int index);
void removeSlot(const StringId & name);
void addCraftingFactory(const FactoryObject & factory);
void removeCraftingFactory(const FactoryObject & factory);
bool addIngredient(ServerObject & component);
bool addIngredient(const NetworkId & resourceId, int count, const NetworkId & sourceId);
bool removeIngredient(ServerObject & component, ServerObject & destination);
bool removeIngredient(const NetworkId & resourceId, int count, ResourceContainerObject & destination);
void destroyAllIngredients();
bool hasIngredient (const NetworkId & componentId) const;
virtual const AttribMap & getAttributes() const;
virtual void setAttribute(const ServerIntangibleObjectTemplate::SchematicAttribute & attribute);
virtual void setAttribute(const StringId & name, float value);
virtual const AttribMap & getResourceMaxAttributes() const;
virtual void setResourceMaxAttribute(const StringId & name, float value);
void setExperimentMod(float mod);
virtual const StringIdList & getExperimentAttributeNames() const;
float getExperimentAttribute(const StringId & name) const;
virtual void setExperimentAttribute(const StringId & name, float value);
float getMinExperimentAttribute(const StringId & name) const;
void setMinExperimentAttribute(const StringId & name, float value);
float getMaxExperimentAttribute(const StringId & name) const;
void setMaxExperimentAttribute(const StringId & name, float value);
float getResourceMaxExperimentAttribute(const StringId & name) const;
void setResourceMaxExperimentAttribute(const StringId & name, float value);
virtual void getAllExperimentAttributeValues(const StringId & name, float & value, float & minValue, float & maxValue, float & resourceMaxValue) const;
virtual void setExperimentAttributeLimits(const StringId & name, float minValue, float maxValue, float resourceMaxValue);
const std::vector<std::string> & getAppearances() const;
void addAppearance(const std::string & appearance);
const std::string getCustomAppearance() const;
void setCustomAppearance(const std::string & appearance);
void setCustomAppearance(int index);
const std::string & getAppearanceData() const;
void setCustomization(const std::string & name, int value, int minValue, int maxValue);
bool setCustomization(int index, int value, ServerObject & prototype);
bool setCustomization(const std::string & name, int value, ServerObject & prototype);
int getItemsPerContainer () const;
void setItemsPerContainer (int count);
float getManufactureTime () const;
void setManufactureTime (float time);
void computeComplexity ();
void signalClientChange ();
void requestSlots (ServerObject & player) const;
virtual bool isMakingObject(void) const;
ServerObject * manufactureObject(const NetworkId & creatorId, ServerObject & container, const SlotId & containerSlotId, bool prototype);
ServerObject * manufactureObject(const Vector & position);
bool setObjectComponents(TangibleObject * object, bool checkResources);
virtual const NetworkId & getDerivedNetworkId() const;
void getAttribBonuses(std::vector<std::pair<int, int> > & attribBonuses) const;
int getAttribBonus(int attribute) const;
void setAttribBonus(int attribute, int bonus);
virtual void getByteStreamFromAutoVariable(const std::string & name, Archive::ByteStream & target) const;
virtual void setAutoVariableFromByteStream(const std::string & name, const Archive::ByteStream & source);
public:
// <name, <isComponent, countPerItem> >
typedef std::pair<Unicode::String, std::pair<bool, int> > IngredientInfo;
typedef stdvector<IngredientInfo>::fwd IngredientInfoVector;
void getIngredientInfo (IngredientInfoVector & iiv) const;
protected:
ServerSynchronizedUi * createSynchronizedUi ();
virtual void initializeFirstTimeObject();
virtual void endBaselines();
virtual const SharedObjectTemplate * getDefaultSharedTemplate() const;
private:
ManufactureSchematicObject();
ManufactureSchematicObject(const ManufactureSchematicObject& rhs);
ManufactureSchematicObject& operator=(const ManufactureSchematicObject& rhs);
void recalculateData();
private:
static const SharedObjectTemplate * m_defaultSharedTemplate; // template to use if no shared template is given
Archive::AutoDeltaVariable<uint32> m_draftSchematicSharedTemplate;
Archive::AutoDeltaVariable<uint32> m_draftSchematic; // draft schematic this schematic is based on
Archive::AutoDeltaVariable<NetworkId> m_creatorId; // id of crafter
Archive::AutoDeltaVariable<Unicode::String> m_creatorName; // name of crafter
Archive::AutoDeltaVariable<int> m_itemsPerContainer; // number of items per container (FactoryObject) when manufacturing
// @todo: move m_attributes to a non-persisted package after old manf schematics are gone
Archive::AutoDeltaMap<StringId, float> m_attributes; // object attributes this schematic affects
Archive::AutoDeltaVariable<float> m_manufactureTime; // time (in secs) to manufacture one object
// not persisted
Archive::AutoDeltaVariable<bool> m_isCrafting;
Archive::AutoDeltaVariable<std::string> m_customAppearance; // this is the custom appearance template
Archive::AutoDeltaVariable<std::string> m_appearanceData; // this is the custom colors data
Archive::AutoDeltaMap<StringId, float> m_resourceMaxAttributes;
Archive::AutoDeltaVariable<uint8> m_schematicChangedSignal;
Archive::AutoDeltaVector<CachedNetworkId> m_factories; // FactoryObjects that have references being used as components
// internal flag - no need to sync
bool m_isMakingObject;
};
//========================================================================
inline const NetworkId & ManufactureSchematicObject::getCreatorId() const
{
return m_creatorId.get();
}
//------------------------------------------------------------------------------
inline int ManufactureSchematicObject::getItemsPerContainer() const
{
return m_itemsPerContainer.get();
}
//------------------------------------------------------------------------------
inline void ManufactureSchematicObject::setItemsPerContainer(int count)
{
m_itemsPerContainer = count;
}
//------------------------------------------------------------------------------
inline float ManufactureSchematicObject::getManufactureTime() const
{
return m_manufactureTime.get();
}
//------------------------------------------------------------------------------
inline void ManufactureSchematicObject::setManufactureTime(float time)
{
m_manufactureTime = time;
}
//------------------------------------------------------------------------------
inline void ManufactureSchematicObject::signalClientChange()
{
m_schematicChangedSignal = static_cast<uint8>(m_schematicChangedSignal.get() + 1);
}
//------------------------------------------------------------------------------
inline const std::string & ManufactureSchematicObject::getAppearanceData() const
{
return m_appearanceData.get();
}
//========================================================================
#endif // INCLUDED_ManufactureSchematicObject_H
@@ -0,0 +1,856 @@
// MissionObject.cpp
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
//-----------------------------------------------------------------------
#include "serverGame/FirstServerGame.h"
#include "serverGame/MissionObject.h"
#include "UnicodeUtils.h"
#include "boost/smart_ptr.hpp"
#include "serverGame/ContainerInterface.h"
#include "serverGame/GameServer.h"
#include "serverGame/MessageToQueue.h"
#include "serverGame/ObjectIdManager.h"
#include "serverGame/ObjectTracker.h"
#include "serverGame/PlayerCreatureController.h"
#include "serverGame/ServerMissionObjectTemplate.h"
#include "serverGame/ServerObjectTemplate.h"
#include "serverGame/ServerWorld.h"
#include "serverScript/GameScriptObject.h"
#include "serverScript/ScriptDictionary.h"
#include "serverScript/ScriptParameters.h"
#include "sharedFoundation/ConstCharCrcLowerString.h"
#include "sharedFoundation/ConstCharCrcString.h"
#include "sharedGame/WaypointData.h"
#include "sharedMessageDispatch/Transceiver.h"
#include "sharedNetworkMessages/MessageQueueMissionCreateRequestData.h"
#include "sharedNetworkMessages/MessageQueueMissionDetailsResponseData.h"
#include "sharedObject/NetworkIdManager.h"
#include "sharedObject/ObjectTemplateList.h"
//-----------------------------------------------------------------------
const SharedObjectTemplate * MissionObject::m_defaultSharedTemplate = NULL;
const char * const s_missionObjectTemplateName = "object/mission/base_mission_object.iff";
//-----------------------------------------------------------------------
MissionObject::MissionObject(const ServerMissionObjectTemplate * t) :
IntangibleObject(t),
m_callback(new MessageDispatch::Callback),
m_description(),
m_difficulty(0),
m_endLocation(),
m_missionCreator(),
m_missionType(),
m_reward(0),
m_rootScriptName(),
m_startLocation(),
m_targetAppearance(),
m_title(),
m_missionHolderId(),
m_status(0),
m_targetName()
{
addMembersToPackages();
ObjectTracker::addMissionObject();
Waypoint & w = const_cast<Waypoint &>(m_waypoint.get());
m_callback->connect(w.getChangeNotification(), *this, &MissionObject::setWaypoint);
m_callback->connect(w.getLoadNotification(), *this, &MissionObject::onWaypointLoad);
}
//-----------------------------------------------------------------------
MissionObject::~MissionObject()
{
ObjectTracker::removeMissionObject();
delete m_callback;
}
//-----------------------------------------------------------------------
MissionObject * MissionObject::createMissionObjectInCreatureMissionBag(CreatureObject * creature)
{
MissionObject * result = 0;
ServerObject * missionBag = creature->getMissionBag();
if(missionBag)
result = safe_cast<MissionObject *>(ServerWorld::createNewObject(s_missionObjectTemplateName, *missionBag, false));
return result;
}
//-----------------------------------------------------------------------
bool MissionObject::canTrade() const
{
return false;
}
//-----------------------------------------------------------------------
bool MissionObject::onContainerAboutToLoseItem(ServerObject * destination, ServerObject& item, ServerObject* transferer)
{
if (transferer)
return false;
return ServerObject::onContainerAboutToLoseItem(destination, item, transferer);
}
//-----------------------------------------------------------------------
bool MissionObject::onContainerAboutToTransfer(ServerObject * destination, ServerObject* transferer)
{
if (transferer)
return false;
return ServerObject::onContainerAboutToTransfer(destination, transferer);
}
//-----------------------------------------------------------------------
int MissionObject::onContainerAboutToGainItem(ServerObject& item, ServerObject* transferer)
{
if (transferer)
return Container::CEC_BlockedByDestinationContainer;
return ServerObject::onContainerAboutToGainItem(item, transferer);
}
//-----------------------------------------------------------------------
/**
* Returns a shared template if none was given for this object.
*
* @return the shared template
*/
const SharedObjectTemplate * MissionObject::getDefaultSharedTemplate(void) const
{
static const ConstCharCrcLowerString templateName("object/mission/base/shared_mission_default.iff");
if (m_defaultSharedTemplate == NULL)
{
m_defaultSharedTemplate = safe_cast<const SharedObjectTemplate *>(
ObjectTemplateList::fetch(templateName));
WARNING_STRICT_FATAL(m_defaultSharedTemplate == NULL, ("Cannot create "
"default shared object template %s", templateName.getString()));
if (m_defaultSharedTemplate != NULL)
ExitChain::add (removeDefaultTemplate, "MissionObject::removeDefaultTemplate");
}
return m_defaultSharedTemplate;
} // MissionObject::getDefaultSharedTemplate
//-----------------------------------------------------------------------
/**
* Cleans up the default shared template.
*/
void MissionObject::removeDefaultTemplate(void)
{
if (m_defaultSharedTemplate != NULL)
{
m_defaultSharedTemplate->releaseReference();
m_defaultSharedTemplate = NULL;
}
} // MissionObject::removeDefaultTemplate
//-----------------------------------------------------------------------
void MissionObject::abortMission()
{
ScriptParams params;
ScriptDictionaryPtr dictionary;
getScriptObject()->makeScriptDictionary(params, dictionary);
if (dictionary.get() != NULL)
{
dictionary->serialize();
MessageToQueue::getInstance().sendMessageToJava(getNetworkId(),
"abortMission", dictionary->getSerializedData(), 0, true);
}
/*
CreatureObject *player = safe_cast<CreatureObject *>(ServerWorld::findObjectByNetworkId(getMissionHolderId()));
if (player)
{
player->abortMission(this);
}
*/
}
//-----------------------------------------------------------------------
void MissionObject::endBaselines()
{
CreatureObject * c = dynamic_cast<CreatureObject *>(NetworkIdManager::getObjectById(m_missionHolderId.get()));
if(c)
{
setMissionHolderId(c->getNetworkId());
}
ServerObject::endBaselines();
}
//-----------------------------------------------------------------------
void MissionObject::endMission(const bool)
{
}
//-----------------------------------------------------------------------
void MissionObject::setMissionHolderId(const NetworkId & h)
{
m_missionHolderId.set(h);
}
//-----------------------------------------------------------------------
void MissionObject::getAttributes(stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const
{
IntangibleObject::getAttributes(data);
std::string const & missionType = getMissionTypeString();
if (strncmp(missionType.c_str(),"space_",6)==0)
{
if (missionType=="space_battle")
data.push_back(std::make_pair(std::string("type"),Unicode::narrowToWide("@space/quest:space_battle"))); // unfortunately, this one is inconsistent
else if (missionType=="space_mining_destroy")
data.push_back(std::make_pair(std::string("type"),Unicode::narrowToWide("@space/quest:space_mining_destroy"))); // unfortunately, this one is also inconsistent
else
data.push_back(std::make_pair(std::string("type"),Unicode::narrowToWide(std::string("@space/quest:") + std::string(missionType,6))));
}
data.push_back(std::make_pair(std::string("description"),Unicode::narrowToWide(std::string("@") + getDescription().getCanonicalRepresentation())));
}
//-----------------------------------------------------------------------
MissionObject * MissionObject::asMissionObject()
{
return this;
}
//-----------------------------------------------------------------------
MissionObject const * MissionObject::asMissionObject() const
{
return this;
}
//-----------------------------------------------------------------------
const NetworkId & MissionObject::getMissionHolderId() const
{
return m_missionHolderId.get();
}
//-----------------------------------------------------------------------
const StringId & MissionObject::getDescription() const
{
return m_description.get();
}
//-----------------------------------------------------------------------
const int MissionObject::getDifficulty() const
{
return m_difficulty.get();
}
//-----------------------------------------------------------------------
const Location & MissionObject::getEndLocation() const
{
return m_endLocation.get();
}
//-----------------------------------------------------------------------
const Unicode::String & MissionObject::getMissionCreator() const
{
return m_missionCreator.get();
}
//-----------------------------------------------------------------------
const unsigned int MissionObject::getMissionType() const
{
return m_missionType.get();
}
//-----------------------------------------------------------------------
const std::string & MissionObject::getMissionTypeString() const
{
// @todo this should be a crc string table!
static const unsigned int destroy = CrcLowerString::calculateCrc("destroy");
static const unsigned int recon = CrcLowerString::calculateCrc("recon");
static const unsigned int deliver = CrcLowerString::calculateCrc("deliver");
static const unsigned int escorttocreator = CrcLowerString::calculateCrc("escorttocreator");
static const unsigned int escort = CrcLowerString::calculateCrc("escort");
static const unsigned int bounty = CrcLowerString::calculateCrc("bounty");
static const unsigned int survey = CrcLowerString::calculateCrc("survey");
static const unsigned int crafting = CrcLowerString::calculateCrc("crafting");
static const unsigned int musician = CrcLowerString::calculateCrc("musician");
static const unsigned int dancer = CrcLowerString::calculateCrc("dancer");
static const unsigned int hunting = CrcLowerString::calculateCrc("hunting");
static const unsigned int space_assassination = CrcLowerString::calculateCrc("space_assassination");
static const unsigned int space_delivery = CrcLowerString::calculateCrc("space_delivery");
static const unsigned int space_delivery_duty = CrcLowerString::calculateCrc("space_delivery_duty");
static const unsigned int space_destroy = CrcLowerString::calculateCrc("space_destroy");
static const unsigned int space_destroy_duty = CrcLowerString::calculateCrc("space_destroy_duty");
static const unsigned int space_surprise_attack = CrcLowerString::calculateCrc("space_surprise_attack");
static const unsigned int space_escort = CrcLowerString::calculateCrc("space_escort");
static const unsigned int space_escort_duty = CrcLowerString::calculateCrc("space_escort duty");
static const unsigned int space_inspection = CrcLowerString::calculateCrc("space_inspection");
static const unsigned int space_patrol = CrcLowerString::calculateCrc("space_patrol");
static const unsigned int space_recovery = CrcLowerString::calculateCrc("space_recovery");
static const unsigned int space_recovery_duty = CrcLowerString::calculateCrc("space_recovery_duty");
static const unsigned int space_rescue = CrcLowerString::calculateCrc("space_rescue");
static const unsigned int space_rescue_duty = CrcLowerString::calculateCrc("space_rescue_duty");
static const unsigned int space_battle = CrcLowerString::calculateCrc("space_battle");
static const unsigned int space_survival = CrcLowerString::calculateCrc("space_survival");
static const unsigned int space_mining_destroy = CrcLowerString::calculateCrc("space_mining_destroy");
if(m_missionType.get() == destroy)
{
static const std::string r = "destroy";
return r;
}
else if(m_missionType.get() == recon)
{
static const std::string r = "recon";
return r;
}
else if(m_missionType.get() == deliver)
{
static const std::string r = "deliver";
return r;
}
else if(m_missionType.get() == escorttocreator)
{
static const std::string r = "escorttocreator";
return r;
}
else if(m_missionType.get() == escort)
{
static const std::string r = "escort";
return r;
}
else if(m_missionType.get() == bounty)
{
static const std::string r = "bounty";
return r;
}
else if(m_missionType.get() == survey)
{
static const std::string r = "survey";
return r;
}
else if(m_missionType.get() == crafting)
{
static const std::string r = "crafting";
return r;
}
else if(m_missionType.get() == musician)
{
static const std::string r = "musician";
return r;
}
else if(m_missionType.get() == dancer)
{
static const std::string r = "dancer";
return r;
}
else if(m_missionType.get() == hunting)
{
static const std::string r = "hunting";
return r;
}
else if(m_missionType.get() == space_assassination)
{
static const std::string r = "space_assassination";
return r;
}
else if(m_missionType.get() == space_delivery)
{
static const std::string r = "space_delivery";
return r;
}
else if(m_missionType.get() == space_delivery_duty)
{
static const std::string r = "space_delivery_duty";
return r;
}
else if(m_missionType.get() == space_destroy)
{
static const std::string r = "space_destroy";
return r;
}
else if(m_missionType.get() == space_destroy_duty)
{
static const std::string r = "space_destroy_duty";
return r;
}
else if(m_missionType.get() == space_surprise_attack)
{
static const std::string r = "space_surprise_attack";
return r;
}
else if(m_missionType.get() == space_escort)
{
static const std::string r = "space_escort";
return r;
}
else if(m_missionType.get() == space_escort_duty)
{
static const std::string r = "space_escort_duty";
return r;
}
else if(m_missionType.get() == space_inspection)
{
static const std::string r = "space_inspection";
return r;
}
else if(m_missionType.get() == space_patrol)
{
static const std::string r = "space_patrol";
return r;
}
else if(m_missionType.get() == space_recovery)
{
static const std::string r = "space_recovery";
return r;
}
else if(m_missionType.get() == space_recovery_duty)
{
static const std::string r = "space_recovery_duty";
return r;
}
else if(m_missionType.get() == space_rescue)
{
static const std::string r = "space_rescue";
return r;
}
else if(m_missionType.get() == space_rescue_duty)
{
static const std::string r = "space_rescue_duty";
return r;
}
else if(m_missionType.get() == space_battle)
{
static const std::string r = "space_battle";
return r;
}
else if(m_missionType.get() == space_survival)
{
static const std::string r = "space_survival";
return r;
}
else if(m_missionType.get() == space_mining_destroy)
{
static const std::string r = "space_mining_destroy";
return r;
}
static const std::string unknown("unknown");
return unknown;
}
//-----------------------------------------------------------------------
const int MissionObject::getReward() const
{
return m_reward.get();
}
//-----------------------------------------------------------------------
const std::string & MissionObject::getRootScriptName() const
{
return m_rootScriptName.get();
}
//-----------------------------------------------------------------------
const Location & MissionObject::getStartLocation() const
{
return m_startLocation.get();
}
//-----------------------------------------------------------------------
const int MissionObject::getStatus() const
{
return m_status.get();
}
//-----------------------------------------------------------------------
const unsigned int MissionObject::getTargetAppearance() const
{
return m_targetAppearance.get();
}
//-----------------------------------------------------------------------
const std::string & MissionObject::getTargetName() const
{
return m_targetName.get();
}
//-----------------------------------------------------------------------
const StringId & MissionObject::getTitle() const
{
return m_title.get();
}
//-----------------------------------------------------------------------
const Waypoint & MissionObject::getWaypoint() const
{
return m_waypoint.get();
}
//-----------------------------------------------------------------------
void MissionObject::grantMissionTo(const NetworkId & target)
{
ScriptParams p;
p.addParam(target);
getScriptObject()->trigAllScripts(Scripting::TRIG_GRANT_MISSION, p);
}
//-----------------------------------------------------------------------
void MissionObject::onAddedToWorld()
{
IntangibleObject::onAddedToWorld();
}
//-----------------------------------------------------------------------
void MissionObject::setDescription(const StringId & d)
{
m_description.set(d);
}
//-----------------------------------------------------------------------
void MissionObject::setDifficulty(const int v)
{
m_difficulty.set(v);
}
//-----------------------------------------------------------------------
void MissionObject::setEndLocation(const Location & v)
{
m_endLocation.set(v);
}
//-----------------------------------------------------------------------
void MissionObject::setMissionCreator(const Unicode::String & c)
{
m_missionCreator.set(c);
}
//-----------------------------------------------------------------------
void MissionObject::setMissionType(const unsigned char t)
{
m_missionType.set(t);
}
//-----------------------------------------------------------------------
void MissionObject::setMissionType(const std::string & t)
{
m_missionType.set(CrcLowerString::calculateCrc(t.c_str()));
}
//-----------------------------------------------------------------------
void MissionObject::setReward(const int v)
{
m_reward.set(v);
}
//-----------------------------------------------------------------------
void MissionObject::setRootScriptName(const std::string & r)
{
if(! m_rootScriptName.get().empty())
{
getScriptObject()->detachScript(getRootScriptName());
}
m_rootScriptName.set(r);
getScriptObject()->attachScript(m_rootScriptName.get(), true);
}
//-----------------------------------------------------------------------
void MissionObject::setStartLocation(const Location & v)
{
m_startLocation.set(v);
}
//-----------------------------------------------------------------------
void MissionObject::setStatus(int newStatus)
{
if(newStatus != 0)
{
m_status.set(m_status.get() + 1);
}
}
//-----------------------------------------------------------------------
void MissionObject::setTargetAppearance(const std::string & a)
{
const ServerObjectTemplate * t = dynamic_cast<const ServerObjectTemplate *>(ObjectTemplateList::fetch(a));
if(t)
{
std::string s = t->getSharedTemplate();
ConstCharCrcString c(s.c_str());
setTargetAppearance(c.getCrc());
}
}
//-----------------------------------------------------------------------
void MissionObject::setTargetAppearance(unsigned int a)
{
m_targetAppearance.set(a);
}
//-----------------------------------------------------------------------
void MissionObject::setTargetName(const std::string & n)
{
m_targetName.set(n);
}
//-----------------------------------------------------------------------
void MissionObject::setTitle(const StringId & t)
{
m_title.set(t);
}
//-----------------------------------------------------------------------
void MissionObject::setWaypoint(const Waypoint & w)
{
m_waypoint.set(w);
}
//-----------------------------------------------------------------------
void MissionObject::onWaypointLoad(Waypoint::ChangeNotification & c)
{
Waypoint & w = const_cast<Waypoint &>(m_waypoint.get());
m_callback->disconnect(w.getChangeNotification(), *this, &MissionObject::setWaypoint);
m_callback->connect(c, *this, &MissionObject::setWaypoint);
}
// ----------------------------------------------------------------------
void MissionObject::initializeFirstTimeObject()
{
m_waypoint.set(Waypoint(ObjectIdManager::getNewObjectId()));
IntangibleObject::initializeFirstTimeObject();
}
// ----------------------------------------------------------------------
void MissionObject::getByteStreamFromAutoVariable(const std::string & name, Archive::ByteStream & target) const
{
if (name == "moCtsPackUnpack")
{
// description
m_description.pack(target);
// difficulty
m_difficulty.pack(target);
// end location
m_endLocation.pack(target);
// mission creator
m_missionCreator.pack(target);
// mission type
m_missionType.pack(target);
// reward
m_reward.pack(target);
// root script name
m_rootScriptName.pack(target);
// start location
m_startLocation.pack(target);
// target appearance
m_targetAppearance.pack(target);
// title
m_title.pack(target);
// mission holder id
// don't need to pack this, will be assigned the id of the destination character object
// status
m_status.pack(target);
// target name
m_targetName.pack(target);
// waypoint
Archive::put(target, m_waypoint.get().getWaypointDataBase());
// mission location target
CreatureObject const * containingPlayer = NULL;
ServerObject const * parent = safe_cast<ServerObject const*>(ContainerInterface::getContainedByObject(*this));
while (parent)
{
containingPlayer = parent->asCreatureObject();
if (containingPlayer && PlayerCreatureController::getPlayerObject(containingPlayer))
break;
containingPlayer = NULL;
parent = safe_cast<ServerObject const*>(ContainerInterface::getContainedByObject(*parent));
}
bool hasMissionLocationTarget = false;
if (containingPlayer)
{
std::vector<LocationData> const & locationData = containingPlayer->getLocationTargets();
for (std::vector<LocationData>::const_iterator iter = locationData.begin(); iter != locationData.end(); ++iter)
{
if (iter->name == Unicode::narrowToWide(getNetworkId().getValueString()))
{
Archive::put(target, true);
Archive::put(target, *iter);
hasMissionLocationTarget = true;
break;
}
}
}
if (!hasMissionLocationTarget)
Archive::put(target, false);
}
else
{
IntangibleObject::getByteStreamFromAutoVariable(name, target);
}
}
// ----------------------------------------------------------------------
void MissionObject::setAutoVariableFromByteStream(const std::string & name, const Archive::ByteStream & source)
{
Archive::ReadIterator ri(source);
if (name == "moCtsPackUnpack")
{
// description
m_description.unpackDelta(ri);
// difficulty
m_difficulty.unpackDelta(ri);
// end location
m_endLocation.unpackDelta(ri);
// mission creator
m_missionCreator.unpackDelta(ri);
// mission type
m_missionType.unpackDelta(ri);
// reward
m_reward.unpackDelta(ri);
// root script name
m_rootScriptName.unpackDelta(ri);
// start location
m_startLocation.unpackDelta(ri);
// target appearance
m_targetAppearance.unpackDelta(ri);
// title
m_title.unpackDelta(ri);
// mission holder id
CreatureObject * containingPlayer = NULL;
ServerObject * parent = safe_cast<ServerObject *>(ContainerInterface::getContainedByObject(*this));
while (parent)
{
containingPlayer = parent->asCreatureObject();
if (containingPlayer && PlayerCreatureController::getPlayerObject(containingPlayer))
break;
containingPlayer = NULL;
parent = safe_cast<ServerObject *>(ContainerInterface::getContainedByObject(*parent));
}
if (containingPlayer)
m_missionHolderId.set(containingPlayer->getNetworkId());
// status
m_status.unpackDelta(ri);
// target name
m_targetName.unpackDelta(ri);
// waypoint
WaypointDataBase waypointDB;
Archive::get(ri, waypointDB);
Waypoint w = m_waypoint.get();
w.setAppearanceNameCrc(waypointDB.m_appearanceNameCrc);
w.setLocation(waypointDB.m_location);
w.setName(waypointDB.m_name);
w.setColor(waypointDB.m_color);
w.setActive(waypointDB.m_active);
m_waypoint.set(w);
DynamicVariableList const & objvar = getObjVars();
if (objvar.hasItem("objTargetWaypoint") && (objvar.getType("objTargetWaypoint") == DynamicVariable::NETWORK_ID))
IGNORE_RETURN(setObjVarItem("objTargetWaypoint", w.getNetworkId()));
// mission location target
bool hasMissionLocationTarget;
Archive::get(ri, hasMissionLocationTarget);
if (hasMissionLocationTarget)
{
LocationData locationData;
Archive::get(ri, locationData);
locationData.name = Unicode::narrowToWide(getNetworkId().getValueString());
if (containingPlayer)
containingPlayer->addLocationTarget(locationData);
}
// questOwner objvar
if (objvar.hasItem("questOwner") && (objvar.getType("questOwner") == DynamicVariable::NETWORK_ID) && containingPlayer)
IGNORE_RETURN(setObjVarItem("questOwner", containingPlayer->getNetworkId()));
// self objvar
if (objvar.hasItem("self") && (objvar.getType("self") == DynamicVariable::NETWORK_ID))
IGNORE_RETURN(setObjVarItem("self", getNetworkId()));
}
else
{
IntangibleObject::setAutoVariableFromByteStream(name, source);
}
addObjectToConcludeList();
}
// ======================================================================
@@ -0,0 +1,134 @@
// MissionObject.h
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
// Author: Justin Randall
#ifndef _INCLUDED_MissionObject_H
#define _INCLUDED_MissionObject_H
//-----------------------------------------------------------------------
#include "serverGame/CreatureObject.h"
#include "serverGame/IntangibleObject.h"
#include "sharedUtility/Location.h"
#include "sharedGame/Waypoint.h"
class Location;
class ServerMissionObjectTemplate;
class Token;
class MessageQueueMissionCreateRequestData;
class MessageQueueMissionDetailsResponse;
namespace MessageDispatch
{
class Callback;
}
//-----------------------------------------------------------------------
class MissionObject : public IntangibleObject
{
public:
virtual ~MissionObject ();
static MissionObject * createMissionObjectInCreatureMissionBag(CreatureObject * creatureWithMissionBag);
virtual MissionObject * asMissionObject();
virtual MissionObject const * asMissionObject() const;
static void removeDefaultTemplate(void);
void abortMission ();
virtual bool canTrade() const;
virtual bool onContainerAboutToLoseItem(ServerObject * destination, ServerObject& item, ServerObject* transferer);
virtual bool onContainerAboutToTransfer(ServerObject * destination, ServerObject* transferer);
virtual int onContainerAboutToGainItem(ServerObject& item, ServerObject* transferer);
void endMission (const bool succeeded);
const NetworkId & getMissionHolderId () const;
virtual void getAttributes (stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const;
/*mission data*/
const int getDifficulty () const;
const StringId & getDescription () const;
const Location & getEndLocation () const;
const Unicode::String & getMissionCreator () const;
const unsigned int getMissionType () const;
const std::string & getMissionTypeString () const;
const int getReward () const;
const std::string & getRootScriptName () const;
const Location & getStartLocation () const;
const unsigned int getTargetAppearance () const;
const std::string & getTargetName () const;
const StringId & getTitle () const;
const int getStatus () const;
const Waypoint & getWaypoint () const;
void grantMissionTo (const NetworkId & target);
virtual void onAddedToWorld ();
void setDescription (const StringId & description);
void setDifficulty (const int difficulty);
void setEndLocation (const Location & endLocation);
void setMissionCreator (const Unicode::String & creator);
void setMissionType (const unsigned char);
void setMissionType (const std::string &);
void setReward (const int reward);
void setRootScriptName (const std::string & rootScriptName);
void setStatus (int newStatus);
void setStartLocation (const Location & startLocation);
void setTargetAppearance (const std::string & appearance);
void setTargetAppearance (unsigned int appearanceNameCrc);
void setTargetName (const std::string & targetName);
void setTitle (const StringId & title);
void setMissionHolderId (const NetworkId & h);
void setWaypoint (const Waypoint & w);
/* end mission data*/
virtual void getByteStreamFromAutoVariable(const std::string & name, Archive::ByteStream & target) const;
virtual void setAutoVariableFromByteStream(const std::string & name, const Archive::ByteStream & source);
protected:
virtual void endBaselines ();
virtual void initializeFirstTimeObject();
virtual const SharedObjectTemplate * getDefaultSharedTemplate(void) const;
friend class ServerMissionObjectTemplate;
MissionObject (const ServerMissionObjectTemplate * missionObjectTemplate);
private:
MissionObject & operator = (const MissionObject & rhs);
MissionObject(const MissionObject & source);
static const ServerMissionObjectTemplate * getBogusMissionObjectTemplate();
void notifyOwnerMissionAccepted();
void notifyOwnerMissionAborted();
void notifyOwnerMissionFailed();
void notifyOwnerMissionSucceeded();
void onWaypointLoad(Waypoint::ChangeNotification &);
private:
static const SharedObjectTemplate * m_defaultSharedTemplate; // template to use if no shared template is given
MessageDispatch::Callback * m_callback;
Archive::AutoDeltaVariable<StringId> m_description;
Archive::AutoDeltaVariable<int> m_difficulty;
Archive::AutoDeltaVariable<Location> m_endLocation;
Archive::AutoDeltaVariable<Unicode::String> m_missionCreator;
Archive::AutoDeltaVariable<unsigned int> m_missionType;
Archive::AutoDeltaVariable<int> m_reward;
Archive::AutoDeltaVariable<std::string> m_rootScriptName;
Archive::AutoDeltaVariable<Location> m_startLocation;
Archive::AutoDeltaVariable<unsigned int> m_targetAppearance;
Archive::AutoDeltaVariable<StringId> m_title;
Archive::AutoDeltaVariable<NetworkId> m_missionHolderId;
Archive::AutoDeltaVariable<int> m_status;
Archive::AutoDeltaVariable<std::string> m_targetName;
Archive::AutoDeltaVariable<Waypoint> m_waypoint;
private:
void addMembersToPackages();
};
//-----------------------------------------------------------------------
#endif // _INCLUDED_MissionObject_H
@@ -0,0 +1,54 @@
// NetworkTriggerVolume.cpp
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
//-----------------------------------------------------------------------
#include "serverGame/FirstServerGame.h"
#include "NetworkTriggerVolume.h"
#include "serverGame/ObserveTracker.h"
#include "serverGame/ServerObject.h"
//-----------------------------------------------------------------------
NetworkTriggerVolume::NetworkTriggerVolume(ServerObject & owner, real radius) :
TriggerVolume(owner, radius, NetworkTriggerVolumeNamespace::NetworkTriggerVolumeName, true)
{
}
//-----------------------------------------------------------------------
NetworkTriggerVolume::~NetworkTriggerVolume()
{
}
//-----------------------------------------------------------------------
bool NetworkTriggerVolume::isNetworkTriggerVolume() const
{
return true;
}
//-----------------------------------------------------------------------
void NetworkTriggerVolume::virtualOnEnter(ServerObject& object)
{
// we never observe ourself due to trigger volumes
if (&object == &getOwner())
return;
Client *client = object.getClient();
if (client)
ObserveTracker::onClientEnteredNetworkTriggerVolume(*client, *this);
}
//-----------------------------------------------------------------------
void NetworkTriggerVolume::virtualOnExit(ServerObject& object)
{
Client *client = object.getClient();
if (client)
ObserveTracker::onClientExitedNetworkTriggerVolume(*client, *this);
}
//-----------------------------------------------------------------------
@@ -0,0 +1,37 @@
// NetworkTriggerVolume.h
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
#ifndef _INCLUDED_NetworkTriggerVolume_H
#define _INCLUDED_NetworkTriggerVolume_H
//-----------------------------------------------------------------------
#include "serverGame/TriggerVolume.h"
//-----------------------------------------------------------------------
namespace NetworkTriggerVolumeNamespace
{
const char NetworkTriggerVolumeName[] = "m_networkUpdateFar";
}
//-----------------------------------------------------------------------
class NetworkTriggerVolume : public TriggerVolume
{
public:
NetworkTriggerVolume(ServerObject & owner, real radius);
virtual ~NetworkTriggerVolume();
virtual bool isNetworkTriggerVolume() const;
private:
virtual void virtualOnEnter(ServerObject& object);
virtual void virtualOnExit(ServerObject& object);
NetworkTriggerVolume(const NetworkTriggerVolume&);
NetworkTriggerVolume& operator= (const NetworkTriggerVolume& );
};
#endif
@@ -0,0 +1,113 @@
// ObjectFactory.cpp
// copyright 2000 Verant Interactive
// Author: Calan Thurow
//Contains the ObjectFactory functions
//(This is excluded from ServerWorld.cpp to reduce compile dependancies.)
//-----------------------------------------------------------------------
//TODO: we don't need to include the headers for all the object types after we remove CreateObjectByType()
//TODO: I have no idea why we need this pragma:
#ifdef WIN32
#pragma warning (disable: 4100)
#endif
#include "serverGame/FirstServerGame.h"
#include "sharedDebug/Profiler.h"
#include "sharedObject/NetworkController.h"
#include "sharedObject/Object.h"
#include "sharedObject/ObjectTemplate.h"
#include "sharedObject/ObjectTemplateList.h"
#include "serverGame/ServerWorld.h"
#include "serverGame/ServerObjectTemplate.h"
#include "sharedFile/TreeFile.h"
#include "sharedFoundation/ConstCharCrcString.h"
#include "sharedFoundation/Crc.h"
#include "serverGame/ObjectIdManager.h"
#include "serverGame/ServerObject.h"
//-----------------------------------------------------------------------
ServerObject * ServerWorld::createObjectFromTemplate(const std::string &templateName, const NetworkId & newId)
{
PROFILER_AUTO_BLOCK_DEFINE("ServerWorld::createObjectFromTemplate1");
return createObjectFromTemplate(Crc::calculate(templateName.c_str()), newId);
} // ServerWorld::createObjectFromTemplate(const std::string &, NetworkId)
//-----------------------------------------------------------------------
ServerObject * ServerWorld::createObjectFromTemplate(uint32 templateCrc, const NetworkId & newId)
{
PROFILER_AUTO_BLOCK_DEFINE("ServerWorld::createObjectFromTemplate1crc");
ObjectTemplate const *objectTemplate = 0;
{
PROFILER_AUTO_BLOCK_DEFINE("ObjectTemplateList::fetch");
objectTemplate = ObjectTemplateList::fetch(templateCrc);
}
WARNING(!objectTemplate, ("Missing Template! Can't create object from "
"template crc %lu(%s), file not found", templateCrc,
ObjectTemplateList::lookUp(templateCrc).getString()));
Object *object = NULL;
if (objectTemplate)
{
ServerObjectTemplate const * serverObjectTemplate = objectTemplate->asServerObjectTemplate();
if ( (serverObjectTemplate == NULL)
|| ((serverObjectTemplate != NULL) && (ObjectTemplateList::lookUp(serverObjectTemplate->getSharedTemplate().c_str()).getCrc() != 0)))
{
PROFILER_AUTO_BLOCK_DEFINE("ObjectTemplate::createObject");
object = objectTemplate->createObject();
if (object)
{
ServerObject *serverObject = object->asServerObject();
if (serverObject)
{
if (newId != NetworkId::cms_invalid)
serverObject->setNetworkId(newId);
else
serverObject->setNetworkId(ObjectIdManager::getInstance().getNewObjectId());
objectTemplate->releaseReference();
return serverObject;
}
WARNING(true, ("tried to create non-server object %lu(%s)", templateCrc,
ObjectTemplateList::lookUp(templateCrc).getString()));
delete object;
}
objectTemplate->releaseReference();
}
else
{
WARNING_STRICT_FATAL(true, ("ServerWorld::createObjectFromTemplate() Unable to create the ServerObject because there is no corresponding SharedObjectTemplate for the ServerObjectTemplate(%lu:%s)", templateCrc, ObjectTemplateList::lookUp(templateCrc).getString()));
}
}
return 0;
} // ServerWorld::createObjectFromTemplate(uint32, NetworkId)
//-----------------------------------------------------------------------
ServerObject * ServerWorld::createObjectFromTemplate(const ServerObjectTemplate &objectTemplate, const NetworkId & newId)
{
PROFILER_AUTO_BLOCK_DEFINE("ServerWorld::createObjectFromTemplate2");
ServerObject *object = safe_cast<ServerObject*>(objectTemplate.createObject());
if (object)
{
if (newId != NetworkId::cms_invalid)
object->setNetworkId(newId);
else
object->setNetworkId(ObjectIdManager::getInstance().getNewObjectId());
return object;
}
return 0;
} // ServerWorld::createObjectFromTemplate(const ServerObjectTemplate &, NetworkId)
//-----------------------------------------------------------------------
@@ -0,0 +1,464 @@
#include "serverGame/FirstServerGame.h"
#include "ObjectTracker.h"
#include "serverGame/CreatureObject.h"
#include "serverGame/PlayerObject.h"
#include "sharedFoundation/ConstCharCrcString.h"
#include "sharedGame/PvpData.h"
#include "sharedTerrain/TerrainObject.h"
int ObjectTracker::m_numBuildings=0;
int ObjectTracker::m_numCreatures=0;
int ObjectTracker::m_numInstallations=0;
int ObjectTracker::m_numObjects=0;
int ObjectTracker::m_numPlayers=0;
time_t ObjectTracker::m_lastTimeCalculateFactionalPlayersCount=0;
int ObjectTracker::m_numPlayersImperial=0;
int ObjectTracker::m_numPlayersRebel=0;
int ObjectTracker::m_numPlayersNeutral=0;
int ObjectTracker::m_numRunTimeRules=0;
int ObjectTracker::m_numTangibles=0;
int ObjectTracker::m_numUniverseObjects=0;
int ObjectTracker::m_numCombatAI=0;
int ObjectTracker::m_numHibernatingAI=0;
int ObjectTracker::m_numDelayedHibernatingAI=0;
int ObjectTracker::m_numIntangibles=0;
int ObjectTracker::m_numGroupObjects=0;
int ObjectTracker::m_numMissionDatas=0;
int ObjectTracker::m_numMissionObjects=0;
int ObjectTracker::m_numMissionListEntries=0;
int ObjectTracker::m_numWaypoints=0;
int ObjectTracker::m_numPlayerQuestObjects = 0;
//==========================================================================================
int ObjectTracker::getNumAI()
{
return m_numCreatures - m_numPlayers;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumBuildings()
{
return m_numBuildings;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumCreatures()
{
return m_numCreatures;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumInstallations()
{
return m_numInstallations;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumObjects()
{
return m_numObjects;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumPlayers()
{
return m_numPlayers;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::getNumPlayersByFaction(int & imperial, int & rebel, int & neutral)
{
time_t const now = ::time(NULL);
if ((now - m_lastTimeCalculateFactionalPlayersCount) > 60)
{
m_numPlayersImperial = 0;
m_numPlayersRebel = 0;
m_numPlayersNeutral = 0;
std::set<PlayerObject const *> const &players = PlayerObject::getAllPlayerObjects();
if (!players.empty())
{
CreatureObject const * creatureObject;
for (std::set<PlayerObject const *>::const_iterator i = players.begin(); i != players.end(); ++i)
{
creatureObject = (*i)->getCreatureObject();
if (creatureObject && creatureObject->isAuthoritative() && creatureObject->getClient())
{
if (PvpData::isImperialFactionId(creatureObject->getPvpFaction()))
++m_numPlayersImperial;
else if (PvpData::isRebelFactionId(creatureObject->getPvpFaction()))
++m_numPlayersRebel;
else
++m_numPlayersNeutral;
}
}
}
m_lastTimeCalculateFactionalPlayersCount = now;
}
imperial = m_numPlayersImperial;
rebel = m_numPlayersRebel;
neutral = m_numPlayersNeutral;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumRunTimeRules()
{
return m_numRunTimeRules;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumTangibles()
{
return m_numTangibles;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumUniverseObjects()
{
return m_numUniverseObjects;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumDynamicAI()
{
int retval = 0;
TerrainObject* const terrain = TerrainObject::getInstance();
if (terrain)
retval = terrain->getNumberOfReferenceObjects() - getNumPlayers();
return retval < 0 ? 0 : retval;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumStaticAI()
{
int retval = getNumAI() - getNumDynamicAI();
return retval < 0 ? 0 : retval;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumCombatAI()
{
return m_numCombatAI;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumHibernatingAI()
{
return m_numHibernatingAI;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumDelayedHibernatingAI()
{
return m_numDelayedHibernatingAI;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumIntangibles()
{
return m_numIntangibles;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumMissionDatas()
{
return m_numMissionDatas;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumMissionObjects()
{
return m_numMissionObjects;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumMissionListEntries()
{
return m_numMissionListEntries;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumGroupObjects()
{
return m_numGroupObjects;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumWaypoints()
{
return m_numWaypoints;
}
//------------------------------------------------------------------------------------------
int ObjectTracker::getNumPlayerQuestObjects()
{
return m_numPlayerQuestObjects;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addBuilding()
{
++m_numBuildings;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addCreature()
{
++m_numCreatures;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addInstallation()
{
++m_numInstallations;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addObject()
{
++m_numObjects;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addPlayer()
{
++m_numPlayers;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addRunTimeRule()
{
++m_numRunTimeRules;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addTangible()
{
++m_numTangibles;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addUniverseObject()
{
++m_numUniverseObjects;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addCombatAI()
{
++m_numCombatAI;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addHibernatingAI()
{
++m_numHibernatingAI;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addDelayedHibernatingAI()
{
++m_numDelayedHibernatingAI;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addIntangible()
{
++m_numIntangibles;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addMissionData()
{
++m_numMissionDatas;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addMissionObject()
{
++m_numMissionObjects;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addMissionListEntry()
{
++m_numMissionListEntries;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addGroupObject()
{
++m_numGroupObjects;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addWaypoint()
{
++m_numWaypoints;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::addPlayerQuestObject()
{
++m_numPlayerQuestObjects;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeBuilding()
{
--m_numBuildings;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeCreature()
{
--m_numCreatures;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeInstallation()
{
--m_numInstallations;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeObject()
{
--m_numObjects;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removePlayer()
{
--m_numPlayers;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeRunTimeRule()
{
--m_numRunTimeRules;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeTangible()
{
--m_numTangibles;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeUniverseObject()
{
--m_numUniverseObjects;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeCombatAI()
{
if (m_numCombatAI > 0) --m_numCombatAI;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeHibernatingAI()
{
if (m_numHibernatingAI > 0)
--m_numHibernatingAI;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeDelayedHibernatingAI()
{
if (m_numDelayedHibernatingAI > 0)
--m_numDelayedHibernatingAI;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeIntangible()
{
--m_numIntangibles;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeMissionData()
{
--m_numMissionDatas;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeMissionObject()
{
--m_numMissionObjects;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeMissionListEntry()
{
--m_numMissionListEntries;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeGroupObject()
{
--m_numGroupObjects;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removeWaypoint()
{
--m_numWaypoints;
}
//------------------------------------------------------------------------------------------
void ObjectTracker::removePlayerQuestObject()
{
--m_numPlayerQuestObjects;
}
//------------------------------------------------------------------------------------------
@@ -0,0 +1,117 @@
#ifndef _ObjectTracker_H_
#define _ObjectTracker_H_
// ======================================================================
class ObjectTracker
{
public:
static int getNumAI();
static int getNumBuildings();
static int getNumCreatures();
static int getNumInstallations();
static int getNumObjects();
static int getNumPlayers();
static void getNumPlayersByFaction(int & imperial, int & rebel, int & neutral);
static int getNumRunTimeRules();
static int getNumTangibles();
static int getNumUniverseObjects();
static int getNumDynamicAI();
static int getNumStaticAI();
static int getNumCombatAI();
static int getNumHibernatingAI();
static int getNumDelayedHibernatingAI();
static int getNumIntangibles();
static int getNumMissionDatas();
static int getNumMissionObjects();
static int getNumGroupObjects();
static int getNumMissionListEntries();
static int getNumWaypoints();
static int getNumPlayerQuestObjects();
static void addBuilding();
static void addCreature();
static void addInstallation();
static void addObject();
static void addPlayer();
static void addRunTimeRule();
static void addTangible();
static void addUniverseObject();
static void addCombatAI();
static void addHibernatingAI();
static void addDelayedHibernatingAI();
static void addIntangible();
static void addGroupObject();
static void addMissionData();
static void addMissionObject();
static void addMissionListEntry();
static void addWaypoint();
static void addPlayerQuestObject();
static void removeBuilding();
static void removeCreature();
static void removeInstallation();
static void removeObject();
static void removePlayer();
static void removeRunTimeRule();
static void removeTangible();
static void removeUniverseObject();
static void removeCombatAI();
static void removeHibernatingAI();
static void removeDelayedHibernatingAI();
static void removeIntangible();
static void removeGroupObject();
static void removeMissionData();
static void removeMissionObject();
static void removeMissionListEntry();
static void removeWaypoint();
static void removePlayerQuestObject();
private:
static int m_numBuildings;
static int m_numCreatures;
static int m_numInstallations;
static int m_numObjects;
static int m_numPlayers;
// we don't want to recalculate the factional
// distribution of the players too often
static time_t m_lastTimeCalculateFactionalPlayersCount;
static int m_numPlayersImperial;
static int m_numPlayersRebel;
static int m_numPlayersNeutral;
static int m_numRunTimeRules;
static int m_numTangibles;
static int m_numUniverseObjects;
static int m_numCombatAI;
static int m_numHibernatingAI;
static int m_numDelayedHibernatingAI;
static int m_numIntangibles;
static int m_numGroupObjects;
static int m_numMissionDatas;
static int m_numMissionObjects;
static int m_numMissionListEntries;
static int m_numWaypoints;
static int m_numPlayerQuestObjects;
private:
ObjectTracker();
~ObjectTracker();
ObjectTracker(const ObjectTracker&);
ObjectTracker& operator= (const ObjectTracker&);
};
#endif
@@ -0,0 +1,61 @@
// ======================================================================
//
// PatrolPathNodeProperty.cpp
// Copyright 2001 Sony Online Entertainment Inc.
// All Rights Reserved.
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/PatrolPathNodeProperty.h"
#include "serverGame/ServerObject.h"
#include <set>
// ======================================================================
PropertyId PatrolPathNodeProperty::getClassPropertyId()
{
// PropertyId id = LabelHash::hashLabel( "Property", "PatrolPathNode" );
// DEBUG_REPORT_LOG(true, ("PatrolPathNodeProperty::getClassPropertyId id = %lx\n", id));
// return id;
return PROPERTY_HASH(PatrolPathNode, 0xef800a48);
}
// ======================================================================
PatrolPathNodeProperty::PatrolPathNodeProperty(Object& thisObject) :
Property(getClassPropertyId(), thisObject),
m_roots(new std::set<CachedNetworkId>)
{
}
//-------------------------------------------------------------------------
PatrolPathNodeProperty::~PatrolPathNodeProperty()
{
delete m_roots;
m_roots = NULL;
}
//-------------------------------------------------------------------------
void PatrolPathNodeProperty::addRoot(const ServerObject & root)
{
m_roots->insert(CachedNetworkId(root));
}
//-------------------------------------------------------------------------
bool PatrolPathNodeProperty::hasRoot(const ServerObject & root) const
{
for (std::set<CachedNetworkId>::const_iterator i = m_roots->begin(); i != m_roots->end(); ++i)
{
if (*i == root.getNetworkId())
return true;
}
return false;
}
// ======================================================================
@@ -0,0 +1,57 @@
// ======================================================================
//
// PatrolPathNodeProperty.h
// Copyright 2001 Sony Online Entertainment Inc.
// All Rights Reserved.
//
// ======================================================================
#ifndef INCLUDED_PatrolPathNodeProperty_H
#define INCLUDED_PatrolPathNodeProperty_H
// ======================================================================
#include "sharedObject/CachedNetworkId.h"
#include "sharedObject/Property.h"
// ======================================================================
class PatrolPathNodeProperty : public Property
{
public:
static PropertyId getClassPropertyId();
public:
PatrolPathNodeProperty(Object& thisObject);
~PatrolPathNodeProperty();
void addRoot(const ServerObject & root);
const stdset<CachedNetworkId>::fwd & getRoots() const;
bool hasRoot(const ServerObject & root) const;
private:
stdset<CachedNetworkId>::fwd * m_roots;
private:
PatrolPathNodeProperty();
PatrolPathNodeProperty(const PatrolPathNodeProperty&);
PatrolPathNodeProperty& operator= (const PatrolPathNodeProperty&);
};
// ======================================================================
inline const stdset<CachedNetworkId>::fwd & PatrolPathNodeProperty::getRoots() const
{
return *m_roots;
}
// ======================================================================
#endif
@@ -0,0 +1,67 @@
// ======================================================================
//
// PatrolPathRootProperty.cpp
// Copyright 2001 Sony Online Entertainment Inc.
// All Rights Reserved.
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/PatrolPathRootProperty.h"
#include "serverGame/ServerObject.h"
#include <set>
// ======================================================================
PropertyId PatrolPathRootProperty::getClassPropertyId()
{
// PropertyId id = LabelHash::hashLabel( "Property", "PatrolPathRoot" );
// DEBUG_REPORT_LOG(true, ("PatrolPathRootProperty::getClassPropertyId id = %lx\n", id));
// return id;
return PROPERTY_HASH(PatrolPathRoot, 0x2df829a2);
}
// ======================================================================
PatrolPathRootProperty::PatrolPathRootProperty(Object& thisObject) :
Property(getClassPropertyId(), thisObject),
m_observerCount(0),
m_patrollers(new std::set<ConstWatcher<ServerObject> >)
{
}
//-------------------------------------------------------------------------
PatrolPathRootProperty::~PatrolPathRootProperty()
{
m_observerCount = 0;
delete m_patrollers;
m_patrollers = 0;
}
//-------------------------------------------------------------------------
void PatrolPathRootProperty::addPatrollingObject(const ServerObject & ai)
{
m_patrollers->insert(ConstWatcher<ServerObject>(&ai));
}
//-------------------------------------------------------------------------
void PatrolPathRootProperty::removePatrollingObject(const ServerObject & ai)
{
m_patrollers->erase(ConstWatcher<ServerObject>(&ai));
}
//-------------------------------------------------------------------------
const std::set<ConstWatcher<ServerObject> > & PatrolPathRootProperty::getPatrollingObjects() const
{
return *m_patrollers;
}
// ======================================================================
@@ -0,0 +1,75 @@
// ======================================================================
//
// PatrolPathRootProperty.h
// Copyright 2001 Sony Online Entertainment Inc.
// All Rights Reserved.
//
// ======================================================================
#ifndef INCLUDED_PatrolPathRootProperty_H
#define INCLUDED_PatrolPathRootProperty_H
// ======================================================================
#include "sharedFoundation/Watcher.h"
#include "sharedObject/Property.h"
class ServerObject;
// ======================================================================
class PatrolPathRootProperty : public Property
{
public:
static PropertyId getClassPropertyId();
public:
PatrolPathRootProperty(Object& thisObject);
~PatrolPathRootProperty();
int getObserverCount() const;
void incrementObserverCount();
void decrementObserverCount();
void addPatrollingObject(const ServerObject & ai);
void removePatrollingObject(const ServerObject & ai);
const stdset<ConstWatcher<ServerObject> >::fwd & getPatrollingObjects() const;
private:
int m_observerCount;
stdset<ConstWatcher<ServerObject> >::fwd * m_patrollers;
private:
PatrolPathRootProperty();
PatrolPathRootProperty(const PatrolPathRootProperty&);
PatrolPathRootProperty& operator= (const PatrolPathRootProperty&);
};
// ======================================================================
inline int PatrolPathRootProperty::getObserverCount() const
{
return m_observerCount;
}
inline void PatrolPathRootProperty::incrementObserverCount()
{
++m_observerCount;
}
inline void PatrolPathRootProperty::decrementObserverCount()
{
--m_observerCount;
}
// ======================================================================
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,309 @@
//========================================================================
//
// PlanetObject.h
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#ifndef INCLUDED_PlanetObject_H
#define INCLUDED_PlanetObject_H
//-----------------------------------------------------------------------
#include "Archive/AutoDeltaMap.h"
#include "Archive/AutoDeltaSetObserver.h"
#include "Archive/AutoDeltaVariableCallback.h"
#include "serverGame/UniverseObject.h"
#include "sharedGame/CollectionsDataTable.h"
#include "sharedGame/LfgCharacterData.h"
#include "sharedGame/TravelPoint.h"
#include "sharedNetworkMessages/MapLocation.h"
#include "sharedNetworkMessages/MapLocationArchive.h"
class CreatureObject;
class ResourceClassObject;
class ResourcePoolObject;
class ResourceTypeObject;
class ScriptParams;
class ServerPlanetObjectTemplate;
class Vector2d;
//-----------------------------------------------------------------------
/**
* A pool of a resource found on a planet.
*
* Represents the planet's supply of a particular resource.
*/
class PlanetObject : public UniverseObject
{
friend class PlanetController;
public:
PlanetObject(const ServerPlanetObjectTemplate* newTemplate);
virtual ~PlanetObject();
virtual Controller* createDefaultController (void);
void addMembersToPackages ();
virtual void unload ();
virtual void onLoadedFromDatabase ();
public:
const std::string & getName () const;
void setPlanetName (const std::string &newName);
virtual void getAttributes (stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const;
//resource pools functions
void getAvailableResourceList (std::vector<ResourceTypeObject const *> &buffer) const;
void getAvailableResourceList (std::vector<ResourceTypeObject const *> &buffer, const ResourceClassObject &masterClass) const;
void debugOutputPools (std::string &output) const;
// weather functions
void setWeather(int weather, float windVelocityX, float windVelocityY, float windVelocityZ);
void getWeather(int & weather, float & windVelocityX, float & windVelocityY, float & windVelocityZ) const;
const std::vector<std::pair<NetworkId, unsigned long> > & getSpawnQueue() const;
public:
// Universe system functions (rebuild data structures on load)
virtual void setupUniverse ();
//-- planetary map support
typedef stdvector<MapLocation>::fwd MapLocationVector;
typedef stdmap<NetworkId, MapLocation>::fwd MapLocationMap;
typedef Archive::AutoDeltaMap<NetworkId, MapLocation> ArchiveMapLocationMap;
typedef stdvector<int>::fwd IntVector;
bool addMapLocation (const MapLocation &location, int mapLocationType, bool enforceLocationCountLimits);
bool removeMapLocation (const NetworkId &id);
bool removeMapLocation (const NetworkId &id, int mapLocationType);
const MapLocationVector & getMapLocations (int mapLocationType) const;
void getMapLocations (MapLocationVector & result) const;
void getMapLocationsByCategories (int mapLocationType, uint8 category, uint8 subCategory, MapLocationVector & result) const;
int getMapLocationVersionForType (int mapLocationType) const;
void getMapLocationCategories (int parentCategory, int mapLocationType, IntVector & result) const;
const MapLocation * getMapLocation (int mapLocationType, const NetworkId & id) const;
//-- travel location support
void addTravelPoint (const std::string& name, const Vector& position_w, int cost, bool interplanetary, TravelPoint::TravelPointType type);
void removeTravelPoint (const std::string& name);
int getNumberOfTravelPoints () const;
const TravelPoint* getTravelPoint (int travelPointIndex) const;
const TravelPoint* getTravelPoint (const std::string& name) const;
void getTravelPointNameList (stdvector<std::string>::fwd& travelPointNameList) const;
void getTravelPointPointList (stdvector<Vector>::fwd& travelPointPointList) const;
void getTravelPointCostList (stdvector<int>::fwd& travelPointCostList) const;
void getTravelPointInterplanetaryList (stdvector<bool>::fwd& travelPointInterplanetaryList) const;
std::set<std::pair<std::pair<int32, std::string>, std::pair<NetworkId, Unicode::String> > > const & getCollectionServerFirst() const;
int getCollectionServerFirstUpdateNumber() const;
void setCollectionServerFirst(const CollectionsDataTable::CollectionInfoCollection& collectionInfo, const NetworkId& claimantId, const Unicode::String& claimantName, const std::string& claimantAccountInfo);
void removeCollectionServerFirst(const CollectionsDataTable::CollectionInfoCollection& collectionInfo);
void setConnectedCharacterLfgData(const NetworkId & characterId, const LfgCharacterData & lfgCharacterData);
std::map<NetworkId, LfgCharacterData> const & getConnectedCharacterLfgData() const;
std::map<std::string, std::pair<int, int> > const & getConnectedCharacterLfgDataFactionalPresence() const;
static ScriptParams const *getConnectedCharacterLfgDataFactionalPresenceTableDictionary();
void setConnectedCharacterGroupData(const NetworkId & characterId, const NetworkId & groupId);
void setConnectedCharacterPlanetData(const NetworkId & characterId, const std::string & planetName);
void setConnectedCharacterRegionData(const NetworkId & characterId, const std::string & regionName);
void setConnectedCharacterPlayerCityData(const NetworkId & characterId, const std::string & playerCityName);
void setConnectedCharacterLevelData(const NetworkId & characterId, int16 level);
void setConnectedCharacterProfessionData(const NetworkId & characterId, LfgCharacterData::Profession profession);
void setConnectedCharacterSearchableByCtsSourceGalaxyData(const NetworkId & characterId, bool searchableByCtsSourceGalaxy);
void setConnectedCharacterDisplayLocationInSearchResultsData(const NetworkId & characterId, bool displayLocationInSearchResults);
void setConnectedCharacterAnonymousData(const NetworkId & characterId, bool anonymous);
void setConnectedCharacterInterestsData(const NetworkId & characterId, BitArray const & interests);
void setConnectedCharacterBiographyData(const NetworkId & characterId, const Unicode::String & biography);
void removeConnectedCharacterBiographyData(const NetworkId & characterId);
std::map<NetworkId, Unicode::String> const & getConnectedCharacterBiographyData() const;
void removeConnectedCharacterData(const NetworkId & characterId);
void addUniverseEvent(std::string const & eventName);
void removeUniverseEvent(std::string const & eventName);
std::string const & getCurrentEvents() const;
void parseCurrentEventsList(std::vector<std::string> & outVector);
void updateGcwTrackingData();
void adjustGcwImperialScore(std::string const & source, CreatureObject * sourceObject, std::string const & gcwCategory, int64 adjustment);
void adjustGcwRebelScore(std::string const & source, CreatureObject * sourceObject, std::string const & gcwCategory, int64 adjustment);
int getGcwImperialScorePercentile(std::string const & gcwCategory) const; // the rebel score is 100 - the imperial score
std::map<std::string, std::pair<int64, int64> > const & getGcwImperialScore() const;
std::map<std::string, std::pair<int64, int64> > const & getGcwRebelScore() const;
protected:
virtual void handleCMessageTo(const MessageToPayload &message);
virtual void endBaselines();
private:
void buildAvailableResourceList () const;
bool getTravelPointIndex (const std::string& name, int& travelPointIndex) const;
void cacheMapLocationsInternal () const;
void incrementMapLocationCacheVersion (int mapLocationType);
Archive::AutoDeltaVariable<int> & getMapLocationVersionForTypeInternal (int mapLocationType) const;
int & getMapLocationListVersionForTypeInternal (int mapLocationType) const;
const MapLocationVector & getMapLocationListForType (int mapLocationType) const;
MapLocationVector & getMapLocationListForTypeInternal (int mapLocationType);
const ArchiveMapLocationMap & getMapLocationMapForType (int mapLocationType) const;
ArchiveMapLocationMap & getMapLocationMapForTypeInternal (int mapLocationType);
void checkUpdateInternalListVersion (int mapLocationType) const;
void connectedCharacterLfgDataFactionalPresenceOnErase(std::string const & keyValue, std::pair<int, int> const & value);
void connectedCharacterLfgDataFactionalPresenceOnInsert(std::string const & keyValue, std::pair<int, int> const & value);
void connectedCharacterLfgDataFactionalPresenceOnSet(std::string const & keyValue, std::pair<int, int> const & oldValue, std::pair<int, int> const & newValue);
private:
struct EventsUpdatedCallback
{
void modified(PlanetObject &target, std::string oldValue, std::string value, bool isLocal);
};
PlanetObject();
PlanetObject(const PlanetObject& rhs);
PlanetObject& operator=(const PlanetObject& rhs);
private:
// BPM PlanetObject : UniverseObject // Begin persisted members.
Archive::AutoDeltaVariable<std::string> m_planetName; ///< The name of the planet. Must match the sceneId of the gameservers that load objects on this planet.
//EPM
//-- Resource data cache
bool mutable m_builtAvailableResourceList;
uint32 mutable m_availableResourceListExpirationTime;
std::vector<ResourceTypeObject const *> mutable m_availableResourceList;
//-- travel location support
Archive::AutoDeltaVector<TravelPoint> m_travelPointList;
// weather support
Archive::AutoDeltaVariable<int> m_weatherIndex;
Archive::AutoDeltaVariable<float> m_windVelocityX;
Archive::AutoDeltaVariable<float> m_windVelocityY;
Archive::AutoDeltaVariable<float> m_windVelocityZ;
//-- planetary map support. @todo remove this from PlanetObject
ArchiveMapLocationMap m_mapLocationMapStatic; // static stuff like buildings & cities
ArchiveMapLocationMap m_mapLocationMapDynamic; // dynamic stuff like camps
ArchiveMapLocationMap m_mapLocationMapPersist; // semi-permanent stuff like player structures, vendors, etc...
mutable Archive::AutoDeltaVariable<int> m_mapLocationVersionStatic; // version numbers for caching
mutable Archive::AutoDeltaVariable<int> m_mapLocationVersionDynamic; //
mutable Archive::AutoDeltaVariable<int> m_mapLocationVersionPersist; //
//-- planetary map local cache. The maps above are synchronized and persisted. The vectors below are stored
//-- and maintained on a per-instance basis.
mutable MapLocationVector m_mapLocationListStatic; // static stuff like buildings & cities
mutable MapLocationVector m_mapLocationListDynamic; // dynamic stuff like camps
mutable MapLocationVector m_mapLocationListPersist; // semi-permanent stuff like player structures, vendors, etc...
mutable int m_mapLocationListVersionStatic; // version numbers for caching
mutable int m_mapLocationListVersionDynamic; //
mutable int m_mapLocationListVersionPersist; //
struct CollectionServerFirstObserver
{
CollectionServerFirstObserver(PlanetObject *planet, Archive::AutoDeltaObserverOp operation);
~CollectionServerFirstObserver();
PlanetObject * m_target;
};
friend struct CollectionServerFirstObserver;
Archive::AutoDeltaSetObserver<std::pair<std::pair<int32, std::string>, std::pair<NetworkId, Unicode::String> >, CollectionServerFirstObserver, PlanetObject> m_collectionServerFirst;
Archive::AutoDeltaVariable<int> m_collectionServerFirstUpdateNumber;
Archive::AutoDeltaMap<NetworkId, LfgCharacterData> m_connectedCharacterLfgData;
Archive::AutoDeltaMap<std::string, std::pair<int, int>, PlanetObject> m_connectedCharacterLfgDataFactionalPresence;
Archive::AutoDeltaMap<std::pair<std::string, std::pair<int, int> >, std::pair<NetworkId, std::pair<int, int> > > m_connectedCharacterLfgDataFactionalPresenceGrid;
Archive::AutoDeltaMap<NetworkId, Unicode::String> m_connectedCharacterBiographyData;
// Event String
Archive::AutoDeltaVariableCallback<std::string, EventsUpdatedCallback, PlanetObject> m_currentEvents;
unsigned long m_nextGcwTrackingUpdate;
std::map<std::string, int64> m_gcwImperialScoreAdjustment;
std::map<std::string, int64> m_gcwRebelScoreAdjustment;
// the score is tracked as a <cumulative score, current period score> pair
Archive::AutoDeltaMap<std::string, std::pair<int64, int64> > m_gcwImperialScore;
Archive::AutoDeltaMap<std::string, std::pair<int64, int64> > m_gcwRebelScore;
};
// ----------------------------------------------------------------------
inline const std::string &PlanetObject::getName() const
{
return m_planetName.get();
}
inline void PlanetObject::getWeather(int & weather, float & windVelocityX,
float & windVelocityY, float & windVelocityZ) const
{
weather = m_weatherIndex.get();
windVelocityX = m_windVelocityX.get();
windVelocityY = m_windVelocityY.get();
windVelocityZ = m_windVelocityZ.get();
}
inline std::set<std::pair<std::pair<int32, std::string>, std::pair<NetworkId, Unicode::String> > > const & PlanetObject::getCollectionServerFirst() const
{
return m_collectionServerFirst.get();
}
inline int PlanetObject::getCollectionServerFirstUpdateNumber() const
{
return m_collectionServerFirstUpdateNumber.get();
}
inline std::map<NetworkId, LfgCharacterData> const & PlanetObject::getConnectedCharacterLfgData() const
{
return m_connectedCharacterLfgData.getMap();
}
inline std::map<std::string, std::pair<int, int> > const & PlanetObject::getConnectedCharacterLfgDataFactionalPresence() const
{
return m_connectedCharacterLfgDataFactionalPresence.getMap();
}
inline std::map<NetworkId, Unicode::String> const & PlanetObject::getConnectedCharacterBiographyData() const
{
return m_connectedCharacterBiographyData.getMap();
}
inline std::map<std::string, std::pair<int64, int64> > const & PlanetObject::getGcwImperialScore() const
{
return m_gcwImperialScore.getMap();
}
inline std::map<std::string, std::pair<int64, int64> > const & PlanetObject::getGcwRebelScore() const
{
return m_gcwRebelScore.getMap();
}
//-----------------------------------------------------------------------
#endif // INCLUDED_PlanetObject_H
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,685 @@
// PlayerQuestObject.cpp
// Copyright 2009, Sony Online Entertainment Inc., all rights reserved.
// Author: Matt Boudreaux
//-----------------------------------------------------------------------
#include "serverGame/FirstServerGame.h"
#include "serverGame/PlayerQuestObject.h"
#include "UnicodeUtils.h"
#include "serverGame/ContainerInterface.h"
#include "serverGame/GameServer.h"
#include "serverGame/NameManager.h"
#include "serverGame/ObjectIdManager.h"
#include "serverGame/ObjectTracker.h"
#include "serverGame/PlayerCreatureController.h"
#include "serverGame/ServerPlayerQuestObjectTemplate.h"
#include "serverGame/ServerObjectTemplate.h"
#include "serverGame/ServerWorld.h"
#include "serverScript/GameScriptObject.h"
#include "serverScript/ScriptDictionary.h"
#include "serverScript/ScriptParameters.h"
#include "sharedFoundation/ConstCharCrcLowerString.h"
#include "sharedFoundation/ConstCharCrcString.h"
#include "sharedObject/NetworkIdManager.h"
#include "sharedObject/ObjectTemplateList.h"
//-----------------------------------------------------------------------
const SharedObjectTemplate * PlayerQuestObject::m_defaultSharedTemplate = NULL;
namespace PlayerQuestObjectNamespace
{
const char * const s_playerQuestObjectTemplateName = "object/player_quest/base_player_quest_object.iff";
const char * const s_tasksObjVar = "pgc.tasks";
const char * const s_numTasksObjVar = "pgc.numTasks";
const char * const s_taskCounterObjVar = "pgc.taskCounters";
const char * const s_taskMaxCounterObjVar = "pgc.taskMaxCounters";
const char * const s_taskStatusObjVar = "pgc.taskStatus";
const char * const s_waypointsObjVar = "pgc.waypoints";
const char * const s_recipeObjVar = "pgc.recipe";
const char * const s_rewardObjVar = "pgc.rewards";
const int s_taskCompleted = 2;
}
using namespace PlayerQuestObjectNamespace;
//-----------------------------------------------------------------------
PlayerQuestObject::PlayerQuestObject(const ServerPlayerQuestObjectTemplate * t) :
TangibleObject(t),
m_tasks(),
m_taskCounters(),
m_taskStatus(),
m_waypoints(),
m_rewards(),
m_creatorName(),
m_completed(),
m_recipe(false),
m_title(),
m_description(),
m_creator(),
m_totalTasks(),
m_difficulty(),
m_taskTitle1(),
m_taskDescription1(),
m_taskTitle2(),
m_taskDescription2(),
m_taskTitle3(),
m_taskDescription3(),
m_taskTitle4(),
m_taskDescription4(),
m_taskTitle5(),
m_taskDescription5(),
m_taskTitle6(),
m_taskDescription6(),
m_taskTitle7(),
m_taskDescription7(),
m_taskTitle8(),
m_taskDescription8(),
m_taskTitle9(),
m_taskDescription9(),
m_taskTitle10(),
m_taskDescription10(),
m_taskTitle11(),
m_taskDescription11(),
m_taskTitle12(),
m_taskDescription12(),
m_taskTitles(),
m_taskDescriptions()
{
addMembersToPackages();
ObjectTracker::addPlayerQuestObject();
m_taskTitles.push_back(&m_taskTitle1);
m_taskTitles.push_back(&m_taskTitle2);
m_taskTitles.push_back(&m_taskTitle3);
m_taskTitles.push_back(&m_taskTitle4);
m_taskTitles.push_back(&m_taskTitle5);
m_taskTitles.push_back(&m_taskTitle6);
m_taskTitles.push_back(&m_taskTitle7);
m_taskTitles.push_back(&m_taskTitle8);
m_taskTitles.push_back(&m_taskTitle9);
m_taskTitles.push_back(&m_taskTitle10);
m_taskTitles.push_back(&m_taskTitle11);
m_taskTitles.push_back(&m_taskTitle12);
m_taskDescriptions.push_back(&m_taskDescription1);
m_taskDescriptions.push_back(&m_taskDescription2);
m_taskDescriptions.push_back(&m_taskDescription3);
m_taskDescriptions.push_back(&m_taskDescription4);
m_taskDescriptions.push_back(&m_taskDescription5);
m_taskDescriptions.push_back(&m_taskDescription6);
m_taskDescriptions.push_back(&m_taskDescription7);
m_taskDescriptions.push_back(&m_taskDescription8);
m_taskDescriptions.push_back(&m_taskDescription9);
m_taskDescriptions.push_back(&m_taskDescription10);
m_taskDescriptions.push_back(&m_taskDescription11);
m_taskDescriptions.push_back(&m_taskDescription12);
}
//-----------------------------------------------------------------------
PlayerQuestObject::~PlayerQuestObject()
{
ObjectTracker::removePlayerQuestObject();
}
//-----------------------------------------------------------------------
bool PlayerQuestObject::canTrade() const
{
return ServerObject::canTrade();
}
//-----------------------------------------------------------------------
PlayerQuestObject * PlayerQuestObject::asPlayerQuestObject()
{
return this;
}
//-----------------------------------------------------------------------
PlayerQuestObject const * PlayerQuestObject::asPlayerQuestObject() const
{
return this;
}
//-----------------------------------------------------------------------
void PlayerQuestObject::removeDefaultTemplate()
{
if(m_defaultSharedTemplate)
{
m_defaultSharedTemplate->releaseReference();
m_defaultSharedTemplate = NULL;
}
}
//-----------------------------------------------------------------------
void PlayerQuestObject::endBaselines()
{
ServerObject::endBaselines();
}
//-----------------------------------------------------------------------
void PlayerQuestObject::getAttributes(stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const
{
TangibleObject::getAttributes(data);
// Push on any extra data here.
}
//-----------------------------------------------------------------------
bool PlayerQuestObject::onContainerAboutToLoseItem(ServerObject * destination, ServerObject& item, ServerObject* transferer)
{
return ServerObject::onContainerAboutToLoseItem(destination, item, transferer);
}
//-----------------------------------------------------------------------
bool PlayerQuestObject::onContainerAboutToTransfer(ServerObject * destination, ServerObject* transferer)
{
return ServerObject::onContainerAboutToTransfer(destination, transferer);
}
//-----------------------------------------------------------------------
int PlayerQuestObject::onContainerAboutToGainItem(ServerObject& item, ServerObject* transferer)
{
return ServerObject::onContainerAboutToGainItem(item, transferer);
}
//-----------------------------------------------------------------------
void PlayerQuestObject::onAddedToWorld()
{
TangibleObject::onAddedToWorld();
}
//-----------------------------------------------------------------------
void PlayerQuestObject::initializeFirstTimeObject()
{
TangibleObject::initializeFirstTimeObject();
saveDataToObjVars();
}
//-----------------------------------------------------------------------
SharedObjectTemplate const * PlayerQuestObject::getDefaultSharedTemplate() const
{
return m_defaultSharedTemplate;
}
//-----------------------------------------------------------------------
PlayerQuestObject * PlayerQuestObject::createPlayerQuestObjectInCreatureDatapad(CreatureObject * creatureWithDatapad)
{
PlayerQuestObject * result = 0;
ServerObject * dataPad = creatureWithDatapad->getDatapad();
if(dataPad)
result = safe_cast<PlayerQuestObject *>(ServerWorld::createNewObject(s_playerQuestObjectTemplateName, *dataPad, false));
return result;
}
//-----------------------------------------------------------------------
PlayerQuestObject * PlayerQuestObject::createPlayerQuestObjectInCreatureInventory(CreatureObject * creatureWithInventory)
{
PlayerQuestObject * result = 0;
ServerObject * inventory = creatureWithInventory->getInventory();
if(inventory)
result = safe_cast<PlayerQuestObject *>(ServerWorld::createNewObject(s_playerQuestObjectTemplateName, *inventory, false));
return result;
}
//-----------------------------------------------------------------------
void PlayerQuestObject::getTasks( std::vector<Unicode::String> &taskVector)
{
taskVector.clear();
for(std::vector<Unicode::String>::size_type i = 0; i < m_tasks.get().size(); ++i)
taskVector.push_back(m_tasks.get()[i]);
}
//-----------------------------------------------------------------------
void PlayerQuestObject::getTaskStatus(std::vector<int> &taskStatus)
{
taskStatus.clear();
for(std::vector<int>::size_type i = 0; i < m_taskStatus.get().size(); ++i)
taskStatus.push_back(m_taskStatus.get()[i]);
}
//-----------------------------------------------------------------------
void PlayerQuestObject::getTaskCounters(std::vector<int> & counterVector)
{
counterVector.clear();
for(std::vector<int>::size_type i = 0; i < m_taskCounters.get().size(); ++i)
counterVector.push_back(m_taskCounters.get()[i].first);
}
//-----------------------------------------------------------------------
void PlayerQuestObject::addNewTask(std::string title, std::string description, int counterMax, std::string waypoint)
{
m_taskStatus.push_back(0);
m_taskCounters.push_back(std::make_pair<int,int>(0, counterMax));
m_waypoints.push_back(waypoint);
m_totalTasks = m_totalTasks.get() + 1;
setTaskTitle(m_totalTasks.get() - 1, title);
setTaskDescription(m_totalTasks.get() - 1, description);
saveDataToObjVars();
}
//-----------------------------------------------------------------------
void PlayerQuestObject::readInObjVarData()
{
// Total Tasks
int numTasks = 0;
if(getObjVars().getItem(s_numTasksObjVar, numTasks))
m_totalTasks = numTasks;
// Task Information
std::vector<Unicode::String> tasks;
if(getObjVars().getItem(s_tasksObjVar, tasks))
{
for(std::vector<Unicode::String>::size_type i = 0; i < tasks.size(); ++i)
m_tasks.push_back(tasks[i]);
}
// Task Counters
std::vector<int> counters;
if(getObjVars().getItem(s_taskCounterObjVar, counters))
{
std::vector<int> maxValues;
if(getObjVars().getItem(s_taskMaxCounterObjVar, maxValues))
for(std::vector<int>::size_type i = 0; i < counters.size(); ++i)
m_taskCounters.push_back(std::make_pair<int,int>(counters[i], maxValues[i]));
}
// Task Status
std::vector<int> status;
if(getObjVars().getItem(s_taskStatusObjVar, status))
{
for(std::vector<int>::size_type i = 0; i < status.size(); ++i)
m_taskStatus.push_back(status[i]);
}
// Waypoints.
std::vector<Unicode::String> waypoints;
if(getObjVars().getItem(s_waypointsObjVar, waypoints))
{
for(std::vector<Unicode::String>::size_type i = 0; i < waypoints.size(); ++i)
m_waypoints.push_back(Unicode::wideToNarrow(waypoints[i]));
}
// Recipe info
int recipe;
if(getObjVars().getItem(s_recipeObjVar, recipe))
{
m_recipe = (recipe == 1 ? true: false);
}
if(m_creator.get() != NetworkId::cms_invalid)
{
m_creatorName = NameManager::getInstance().getPlayerFullName(m_creator.get());
}
// Rewards
std::string rewards;
if(getObjVars().getItem(s_rewardObjVar, rewards))
{
m_rewards = rewards;
}
checkForCompleted();
fixObjVarDelimiter();
}
//-----------------------------------------------------------------------
void PlayerQuestObject::saveDataToObjVars()
{
setObjVarItem(s_tasksObjVar, m_tasks.get());
setObjVarItem(s_numTasksObjVar, m_totalTasks.get());
setObjVarItem(s_taskStatusObjVar, m_taskStatus.get());
// Save counter obj vars.
std::vector<int> currentValues;
std::vector<int> maxValues;
std::vector< std::pair<int,int> >::const_iterator iter = m_taskCounters.begin();
for(; iter != m_taskCounters.end(); ++iter)
{
currentValues.push_back((*iter).first);
maxValues.push_back((*iter).second);
}
setObjVarItem(s_taskCounterObjVar, currentValues);
setObjVarItem(s_taskMaxCounterObjVar, maxValues);
//Waypoints
std::vector<Unicode::String> convertedWaypoints;
for(std::vector<std::string>::size_type i = 0; i < m_waypoints.size(); ++i)
{
convertedWaypoints.push_back(Unicode::narrowToWide(m_waypoints.get()[i]));
}
setObjVarItem(s_waypointsObjVar, convertedWaypoints);
setObjVarItem(s_recipeObjVar, m_recipe.get() ? 1 : 0);
setObjVarItem(s_rewardObjVar, m_rewards.get());
}
//-----------------------------------------------------------------------
void PlayerQuestObject::onLoadedFromDatabase()
{
readInObjVarData();
}
//-----------------------------------------------------------------------
int PlayerQuestObject::getTaskStatus(int taskIndex)
{
if(taskIndex < 0 || static_cast<unsigned int>(taskIndex) > m_taskStatus.size())
return -1;
return m_taskStatus.get()[taskIndex];
}
//-----------------------------------------------------------------------
void PlayerQuestObject::setTaskStatus(int taskIndex, int status)
{
if(taskIndex < 0 || static_cast<unsigned int>(taskIndex) > m_taskStatus.size())
return;
m_taskStatus.set(taskIndex, status);
saveDataToObjVars();
checkForCompleted();
}
//-----------------------------------------------------------------------
void PlayerQuestObject::setTaskTitle(int index, std::string title)
{
if(index < 0 || index >= m_totalTasks.get())
return;
*(m_taskTitles[index]) = title;
}
//-----------------------------------------------------------------------
std::string const & PlayerQuestObject::getTaskTitle(int index)
{
return m_taskTitles[index]->get();
}
//-----------------------------------------------------------------------
void PlayerQuestObject::setTaskDescription(int index, std::string description)
{
if(index < 0 || index >= m_totalTasks.get())
return;
*(m_taskDescriptions[index]) = description;
}
//-----------------------------------------------------------------------
std::string const & PlayerQuestObject::getTaskDescription(int index)
{
return m_taskDescriptions[index]->get();
}
//-----------------------------------------------------------------------
void PlayerQuestObject::setTaskCounter(int index, int value)
{
int maxValue = m_taskCounters.get()[index].second;
m_taskCounters.set(static_cast<unsigned int>(index), std::make_pair<int, int>(value, maxValue));
saveDataToObjVars();
}
//-----------------------------------------------------------------------
void PlayerQuestObject::checkForCompleted()
{
std::vector<int>::size_type i = 0;
for(; i < m_taskStatus.size(); ++i)
{
if(m_taskStatus.get()[i] != s_taskCompleted)
{
m_completed = false;
return;
}
}
m_completed = true;
}
//-----------------------------------------------------------------------
void PlayerQuestObject::setRecipe(bool recipe)
{
m_recipe = recipe;
saveDataToObjVars();
}
//-----------------------------------------------------------------------
void PlayerQuestObject::addRecipeTaskData(std::string data)
{
m_tasks.push_back(Unicode::narrowToWide(data));
saveDataToObjVars();
}
//-----------------------------------------------------------------------
void PlayerQuestObject::setRecipeTaskData(int index, std::string data)
{
m_tasks.set(static_cast<unsigned int>(index), Unicode::narrowToWide(data));
saveDataToObjVars();
}
//-----------------------------------------------------------------------
std::string const PlayerQuestObject::getRecipeTaskData(int index)
{
return Unicode::wideToNarrow(m_tasks.get()[index]);
}
//-----------------------------------------------------------------------
void PlayerQuestObject::setRewards(std::string data)
{
m_rewards = data;
saveDataToObjVars();
}
//-----------------------------------------------------------------------
std::string const & PlayerQuestObject::getRewards()
{
return m_rewards.get();
}
//-----------------------------------------------------------------------
void PlayerQuestObject::setCreator(NetworkId const & creator)
{
m_creator = creator;
if(m_creator.get() != NetworkId::cms_invalid)
{
m_creatorName = NameManager::getInstance().getPlayerFullName(m_creator.get());
}
}
void PlayerQuestObject::resetAllData()
{
for(unsigned int i = 0; i < m_taskTitles.size(); ++i)
{
*(m_taskTitles[i]) = "";
}
for(unsigned int i = 0; i < m_taskDescriptions.size(); ++i)
{
*(m_taskDescriptions[i]) = "";
}
m_title = "";
m_description = "";
m_tasks.clear();
m_totalTasks = 0;
m_difficulty = 0;
m_taskStatus.clear();
m_taskCounters.clear();
m_waypoints.clear();
m_recipe = 0;
m_rewards = "";
m_completed = false;
m_creator = NetworkId::cms_invalid;
m_creatorName = "";
saveDataToObjVars();
}
void PlayerQuestObject::getByteStreamFromAutoVariable(const std::string & name, Archive::ByteStream & target) const
{
if(name == "PGCPacked")
{
// title
m_title.pack(target);
// description
m_description.pack(target);
// creator
m_creator.pack(target);
// total tasks
m_totalTasks.pack(target);
// difficulty
m_difficulty.pack(target);
// All our task titles/descriptions
for(int i = 0; i < m_totalTasks.get(); ++i)
{
m_taskTitles[i]->pack(target);
m_taskDescriptions[i]->pack(target);
}
// Everything else should be stored as objvars.
}
else
{
TangibleObject::getByteStreamFromAutoVariable(name, target);
}
}
void PlayerQuestObject::setAutoVariableFromByteStream(const std::string & name, const Archive::ByteStream & source)
{
Archive::ReadIterator ri(source);
if(name == "PGCPacked")
{
// title
m_title.unpackDelta(ri);
// description
m_description.unpackDelta(ri);
// creator
m_creator.unpackDelta(ri);
// total tasks
m_totalTasks.unpackDelta(ri);
// difficulty
m_difficulty.unpackDelta(ri);
// All our task titles/descriptions
for(int i = 0; i < m_totalTasks.get(); ++i)
{
m_taskTitles[i]->unpackDelta(ri);
m_taskDescriptions[i]->unpackDelta(ri);
}
// Make sure our other auto-deltas are up to date.
readInObjVarData();
}
else
{
TangibleObject::setAutoVariableFromByteStream(name, source);
}
addObjectToConcludeList();
}
void PlayerQuestObject::fixObjVarDelimiter()
{
// This should only affect Recipe/Task Data and Rewards string
bool saveNeeded = false;
for(unsigned int i = 0; i < m_tasks.size(); ++i)
{
std::string narrowString = Unicode::wideToNarrow(m_tasks[i]);
std::string::size_type iter = narrowString.find('|');
while(iter != std::string::npos)
{
narrowString.replace(iter, iter, 1, '~');
saveNeeded = true;
iter = narrowString.find('|', iter + 1);
}
if(saveNeeded)
m_tasks.set(i,Unicode::narrowToWide(narrowString));
}
std::string rewards = m_rewards.get();
std::string::size_type iter = rewards.find('|');
while(iter != std::string::npos)
{
rewards.replace(iter, iter, 1, '~');
saveNeeded = true;
iter = rewards.find('|', iter + 1);
}
if(saveNeeded)
{
m_rewards = rewards;
saveDataToObjVars();
}
}
@@ -0,0 +1,237 @@
// PlayerQuestObject.h
// Copyright 2009, Sony Online Entertainment Inc., all rights reserved.
// Author: Matt Boudreaux
#ifndef _INCLUDED_PlayerQuestObject_H
#define _INCLUDED_PlayerQuestObject_H
//-----------------------------------------------------------------------
#include "serverGame/CreatureObject.h"
#include "serverGame/TangibleObject.h"
class ServerPlayerQuestObjectTemplate;
//-----------------------------------------------------------------------
class PlayerQuestObject : public TangibleObject
{
public:
virtual ~PlayerQuestObject ();
static PlayerQuestObject * createPlayerQuestObjectInCreatureDatapad(CreatureObject * creatureWithDatapad);
static PlayerQuestObject * createPlayerQuestObjectInCreatureInventory(CreatureObject * creatureWithInventory);
virtual PlayerQuestObject * asPlayerQuestObject();
virtual PlayerQuestObject const * asPlayerQuestObject() const;
static void removeDefaultTemplate(void);
virtual bool canTrade() const;
virtual bool onContainerAboutToLoseItem(ServerObject * destination, ServerObject& item, ServerObject* transferer);
virtual bool onContainerAboutToTransfer(ServerObject * destination, ServerObject* transferer);
virtual int onContainerAboutToGainItem(ServerObject& item, ServerObject* transferer);
virtual void getAttributes (stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const;
virtual void onAddedToWorld ();
int getTotalTasks();
void getTasks(std::vector<Unicode::String> & taskVector );
void getTaskCounters(std::vector<int> & counterVector);
void getTaskStatus(std::vector<int> & taskStatus);
int getTaskStatus(int taskIndex);
void addNewTask(std::string title, std::string description, int counterMax, std::string waypoint);
void setTaskStatus(int taskIndex, int status);
void setQuestTitle(std::string title);
std::string const & getQuestTitle();
void setQuestDescription(std::string description);
std::string const & getQuestDescription();
void setTaskTitle(int index, std::string title);
std::string const & getTaskTitle(int index);
void setTaskDescription(int index, std::string description);
std::string const & getTaskDescription(int index);
void setQuestDifficulty(int difficulty);
int getQuestDifficulty();
int getTaskCounter(int index);
void setTaskCounter(int index, int value);
std::string const & getWaypoint(int index);
bool isCompleted() const;
void setRecipe(bool recipe);
bool isRecipe() const;
void addRecipeTaskData(std::string data);
void setRecipeTaskData(int index, std::string data);
std::string const getRecipeTaskData(int index);
void setRewards(std::string data);
std::string const & getRewards();
void setCreator(NetworkId const & creator);
void resetAllData();
virtual void getByteStreamFromAutoVariable(const std::string & name, Archive::ByteStream & target) const;
virtual void setAutoVariableFromByteStream(const std::string & name, const Archive::ByteStream & source);
protected:
virtual void endBaselines ();
virtual void initializeFirstTimeObject();
virtual const SharedObjectTemplate * getDefaultSharedTemplate(void) const;
friend class ServerPlayerQuestObjectTemplate;
PlayerQuestObject (const ServerPlayerQuestObjectTemplate * playerQuestObjectTemplate);
private:
PlayerQuestObject & operator = (const PlayerQuestObject & rhs);
PlayerQuestObject(const PlayerQuestObject & source);
void readInObjVarData();
void saveDataToObjVars();
void checkForCompleted();
void fixObjVarDelimiter();
virtual void onLoadedFromDatabase();
private:
static const SharedObjectTemplate * m_defaultSharedTemplate; // template to use if no shared template is given
// Auto deltas.
Archive::AutoDeltaVector<Unicode::String> m_tasks;
Archive::AutoDeltaVector<std::pair<int, int> > m_taskCounters;
Archive::AutoDeltaVector<int> m_taskStatus;
Archive::AutoDeltaVector<std::string> m_waypoints;
Archive::AutoDeltaVariable<std::string> m_rewards;
Archive::AutoDeltaVariable<std::string> m_creatorName;
Archive::AutoDeltaVariable<bool> m_completed;
Archive::AutoDeltaVariable<bool> m_recipe;
Archive::AutoDeltaVariable<std::string> m_title;
Archive::AutoDeltaVariable<std::string> m_description;
Archive::AutoDeltaVariable<NetworkId> m_creator;
Archive::AutoDeltaVariable<int> m_totalTasks;
Archive::AutoDeltaVariable<int> m_difficulty;
// Task Titles and Descriptions.
Archive::AutoDeltaVariable<std::string> m_taskTitle1;
Archive::AutoDeltaVariable<std::string> m_taskDescription1;
Archive::AutoDeltaVariable<std::string> m_taskTitle2;
Archive::AutoDeltaVariable<std::string> m_taskDescription2;
Archive::AutoDeltaVariable<std::string> m_taskTitle3;
Archive::AutoDeltaVariable<std::string> m_taskDescription3;
Archive::AutoDeltaVariable<std::string> m_taskTitle4;
Archive::AutoDeltaVariable<std::string> m_taskDescription4;
Archive::AutoDeltaVariable<std::string> m_taskTitle5;
Archive::AutoDeltaVariable<std::string> m_taskDescription5;
Archive::AutoDeltaVariable<std::string> m_taskTitle6;
Archive::AutoDeltaVariable<std::string> m_taskDescription6;
Archive::AutoDeltaVariable<std::string> m_taskTitle7;
Archive::AutoDeltaVariable<std::string> m_taskDescription7;
Archive::AutoDeltaVariable<std::string> m_taskTitle8;
Archive::AutoDeltaVariable<std::string> m_taskDescription8;
Archive::AutoDeltaVariable<std::string> m_taskTitle9;
Archive::AutoDeltaVariable<std::string> m_taskDescription9;
Archive::AutoDeltaVariable<std::string> m_taskTitle10;
Archive::AutoDeltaVariable<std::string> m_taskDescription10;
Archive::AutoDeltaVariable<std::string> m_taskTitle11;
Archive::AutoDeltaVariable<std::string> m_taskDescription11;
Archive::AutoDeltaVariable<std::string> m_taskTitle12;
Archive::AutoDeltaVariable<std::string> m_taskDescription12;
// Helper containers to keep access simple.
std::vector<Archive::AutoDeltaVariable<std::string> *> m_taskTitles;
std::vector<Archive::AutoDeltaVariable<std::string> *> m_taskDescriptions;
private:
void addMembersToPackages();
};
//-----------------------------------------------------------------------
inline int PlayerQuestObject::getTotalTasks()
{
return m_totalTasks.get();
}
//-----------------------------------------------------------------------
inline void PlayerQuestObject::setQuestTitle(std::string title)
{
m_title = title;
}
//-----------------------------------------------------------------------
inline std::string const & PlayerQuestObject::getQuestTitle()
{
return m_title.get();
}
//-----------------------------------------------------------------------
inline void PlayerQuestObject::setQuestDescription(std::string description)
{
m_description = description;
}
//-----------------------------------------------------------------------
inline std::string const & PlayerQuestObject::getQuestDescription()
{
return m_description.get();
}
//-----------------------------------------------------------------------
inline void PlayerQuestObject::setQuestDifficulty(int difficulty)
{
m_difficulty = difficulty;
}
//-----------------------------------------------------------------------
inline int PlayerQuestObject::getQuestDifficulty()
{
return m_difficulty.get();
}
//-----------------------------------------------------------------------
inline int PlayerQuestObject::getTaskCounter(int index)
{
return m_taskCounters.get()[index].first;
}
//-----------------------------------------------------------------------
inline std::string const & PlayerQuestObject::getWaypoint(int index)
{
return m_waypoints.get()[index];
}
//-----------------------------------------------------------------------
inline bool PlayerQuestObject::isCompleted() const
{
return m_completed.get();
}
//-----------------------------------------------------------------------
inline bool PlayerQuestObject::isRecipe() const
{
return m_recipe.get();
}
#endif // _INCLUDED_PlayerQuestObject_H
@@ -0,0 +1,70 @@
// ======================================================================
//
// PortalTriggerVolume.cpp
//
// Copyright 2000-04 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "PortalTriggerVolume.h"
#include "serverGame/ObserveTracker.h"
#include "serverGame/ServerObject.h"
// ======================================================================
namespace PortalTriggerVolumeNamespace
{
const char* ms_name = "portalTriggerVolume";
}
using namespace PortalTriggerVolumeNamespace;
// ======================================================================
PortalTriggerVolume::PortalTriggerVolume(ServerObject &owner, real radius) :
TriggerVolume(owner, radius, ms_name, true)
{
}
// ----------------------------------------------------------------------
PortalTriggerVolume::~PortalTriggerVolume()
{
}
// ----------------------------------------------------------------------
const char* PortalTriggerVolume::getName()
{
return ms_name;
}
// ----------------------------------------------------------------------
void PortalTriggerVolume::virtualOnEnter(ServerObject &object)
{
Client *client = object.getClient();
if (client)
ObserveTracker::onClientEnteredPortalTriggerVolume(*client, *this);
}
// ----------------------------------------------------------------------
void PortalTriggerVolume::virtualOnExit(ServerObject &object)
{
Client *client = object.getClient();
if (client)
ObserveTracker::onClientExitedPortalTriggerVolume(*client, *this);
}
// ----------------------------------------------------------------------
bool PortalTriggerVolume::isPortalTriggerVolume() const
{
return true;
}
// ======================================================================
@@ -0,0 +1,39 @@
// ======================================================================
//
// PortalTriggerVolume.h
//
// Copyright 2000-04 Sony Online Entertainment
//
// ======================================================================
#ifndef _INCLUDED_PortalTriggerVolume_H
#define _INCLUDED_PortalTriggerVolume_H
// ======================================================================
#include "serverGame/TriggerVolume.h"
// ======================================================================
class PortalTriggerVolume : public TriggerVolume
{
public:
PortalTriggerVolume(ServerObject &owner, real radius);
virtual ~PortalTriggerVolume();
virtual bool isPortalTriggerVolume() const;
static char const *getName();
private:
virtual void virtualOnEnter(ServerObject &object);
virtual void virtualOnExit(ServerObject &object);
PortalTriggerVolume(PortalTriggerVolume const &);
PortalTriggerVolume &operator=(PortalTriggerVolume const &);
};
// ======================================================================
#endif // _INCLUDED_PortalTriggerVolume_H
@@ -0,0 +1,128 @@
// ======================================================================
//
// PvpEnemiesObserver.cpp
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/PvpEnemiesObserver.h"
#include "serverGame/BuildingObject.h"
#include "serverGame/CellObject.h"
#include "serverGame/Client.h"
#include "serverGame/ContainerInterface.h"
#include "serverGame/CreatureObject.h"
#include "serverGame/Pvp.h"
#include "sharedNetworkMessages/UpdateCellPermissionMessage.h"
#include "sharedObject/Container.h"
// ======================================================================
static std::set<CreatureObject *> s_activeUpdaters;
// ======================================================================
PvpEnemiesObserver::PvpEnemiesObserver(TangibleObject *who, Archive::AutoDeltaObserverOp operation) :
m_profilerBlock("PvpEnemiesObserver"),
m_obj(0),
m_pvpObserver(who, operation),
m_hadAnyAlignedTimedEnemyFlag(false),
m_hadAnyBountyDuelEnemyFlag(false)
{
CreatureObject * const co = who ? who->asCreatureObject() : 0;
if (!co || !co->getClient() || s_activeUpdaters.find(co) != s_activeUpdaters.end())
return;
m_obj = co;
s_activeUpdaters.insert(co);
m_hadAnyAlignedTimedEnemyFlag = Pvp::hasAnyAlignedTimedEnemyFlag(*co);
m_hadAnyBountyDuelEnemyFlag = Pvp::hasAnyBountyDuelEnemyFlag(*co);
}
// ----------------------------------------------------------------------
PvpEnemiesObserver::~PvpEnemiesObserver()
{
if (!m_obj)
return;
s_activeUpdaters.erase(m_obj);
Client * const client = m_obj->getClient();
if (client)
{
bool const alignedTimedEnemyFlagChanged = (m_hadAnyAlignedTimedEnemyFlag != Pvp::hasAnyAlignedTimedEnemyFlag(*m_obj));
bool const bountyDuelEnemyFlagChanged = (m_hadAnyBountyDuelEnemyFlag != Pvp::hasAnyBountyDuelEnemyFlag(*m_obj));
if (!alignedTimedEnemyFlagChanged && !bountyDuelEnemyFlagChanged)
return;
// run through all buildings we are observing that care about this and send updates
Client::ObservingList const &observing = client->getObserving();
for (Client::ObservingList::const_iterator i = observing.begin(); i != observing.end(); ++i)
{
BuildingObject * const building = (*i)->asBuildingObject();
if (building && !building->playersWithAlignedEnemyFlagsAllowed())
{
// This building cares about enemy flags, so send cell permission updates
Container * const container = ContainerInterface::getContainer(*building);
for (ContainerIterator j = container->begin(); j != container->end(); ++j)
{
Object const * const o = (*j).getObject();
if (o)
{
ServerObject const * const so = o->asServerObject();
if (so)
{
CellObject const * const co = so->asCellObject();
if (co)
{
// We cannot possibly be allowed unless we just lost our last aligned temp enemy flag,
// so only query our status if that is the case. Likewise, we don't need to send a
// status update if we are still not allowed after losing our last aligned temp
// enemy flag. We will still generate unnecesary messages when we were previously
// not allowed, and are gaining our first aligned temp enemy flag, but not needing
// to know the old state allows us to avoid a lot of work.
bool allowed = false;
if ((alignedTimedEnemyFlagChanged && m_hadAnyAlignedTimedEnemyFlag) || (bountyDuelEnemyFlagChanged && m_hadAnyBountyDuelEnemyFlag))
allowed = co->isAllowed(*m_obj);
if (allowed || (alignedTimedEnemyFlagChanged && !m_hadAnyAlignedTimedEnemyFlag) || (bountyDuelEnemyFlagChanged && !m_hadAnyBountyDuelEnemyFlag))
{
UpdateCellPermissionMessage const permissionsMessage(co->getNetworkId(), allowed);
client->send(permissionsMessage, true);
}
}
}
}
}
}
}
// expel from the building we are in if no longer allowed
if ((alignedTimedEnemyFlagChanged && !m_hadAnyAlignedTimedEnemyFlag) || (bountyDuelEnemyFlagChanged && !m_hadAnyBountyDuelEnemyFlag)) // if we didn't have aligned enemy flags but we do now
{
Object * const o = m_obj->getAttachedTo();
if (o)
{
ServerObject * const so = o->asServerObject();
if (so)
{
CellObject * const co = so->asCellObject();
if (co)
{
BuildingObject * const bo = co->getOwnerBuilding();
if (bo && !bo->playersWithAlignedEnemyFlagsAllowed())
bo->expelObject(*m_obj);
}
}
}
}
}
}
// ======================================================================
@@ -0,0 +1,46 @@
// ======================================================================
//
// PvpEnemiesObserver.h
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#ifndef _PvpEnemiesObserver_H_
#define _PvpEnemiesObserver_H_
// ======================================================================
#include "Archive/AutoDeltaObserverOps.h"
#include "serverGame/PvpUpdateObserver.h"
#include "sharedDebug/Profiler.h"
// ======================================================================
class CreatureObject;
class TangibleObject;
// ======================================================================
class PvpEnemiesObserver
{
public:
PvpEnemiesObserver(TangibleObject *who, Archive::AutoDeltaObserverOp operation);
~PvpEnemiesObserver();
private:
PvpEnemiesObserver(PvpEnemiesObserver const &);
PvpEnemiesObserver& operator=(PvpEnemiesObserver const &);
private:
ProfilerAutoBlock m_profilerBlock;
CreatureObject *m_obj;
PvpUpdateObserver m_pvpObserver;
bool m_hadAnyAlignedTimedEnemyFlag;
bool m_hadAnyBountyDuelEnemyFlag;
};
// ======================================================================
#endif // _PvpEnemiesObserver_H_
@@ -0,0 +1,29 @@
// ======================================================================
//
// PvpUpdateAndCellPermissionsObserver.cpp
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/PvpUpdateAndCellPermissionsObserver.h"
#include "serverGame/TangibleObject.h"
// ======================================================================
PvpUpdateAndCellPermissionsObserver::PvpUpdateAndCellPermissionsObserver(TangibleObject *who, Archive::AutoDeltaObserverOp operation) :
m_profilerBlock("PvpUpdateAndCellPermissionsObserver"),
m_pvpObserver(who, operation),
m_cellPermsObserver(who ? who->asCreatureObject() : 0)
{
}
// ----------------------------------------------------------------------
PvpUpdateAndCellPermissionsObserver::~PvpUpdateAndCellPermissionsObserver()
{
}
// ======================================================================
@@ -0,0 +1,44 @@
// ======================================================================
//
// PvpUpdateAndCellPermissionsObserver.h
//
// Copyright 2003 Sony Online Entertainment
//
// ======================================================================
#ifndef _PvpUpdateAndCellPermissionsObserver_H_
#define _PvpUpdateAndCellPermissionsObserver_H_
// ======================================================================
#include "Archive/AutoDeltaObserverOps.h"
#include "serverGame/PvpUpdateObserver.h"
#include "serverGame/CellPermissions.h"
#include "sharedDebug/Profiler.h"
// ======================================================================
class TangibleObject;
// ======================================================================
class PvpUpdateAndCellPermissionsObserver
{
public:
PvpUpdateAndCellPermissionsObserver(TangibleObject *who, Archive::AutoDeltaObserverOp operation);
~PvpUpdateAndCellPermissionsObserver();
private:
PvpUpdateAndCellPermissionsObserver(PvpUpdateAndCellPermissionsObserver const &);
PvpUpdateAndCellPermissionsObserver& operator=(PvpUpdateAndCellPermissionsObserver const &);
private:
ProfilerAutoBlock m_profilerBlock;
PvpUpdateObserver m_pvpObserver;
CellPermissions::ViewerChangeObserver m_cellPermsObserver;
};
// ======================================================================
#endif // _PvpUpdateAndCellPermissionsObserver_H_
@@ -0,0 +1,676 @@
// ======================================================================
//
// ResourceContainerObject.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/ResourceContainerObject.h"
#include "UnicodeUtils.h"
#include "serverGame/ContainerInterface.h"
#include "serverGame/ResourceContainerController.h"
#include "serverGame/ResourceTypeObject.h"
#include "serverGame/ServerMessageForwarding.h"
#include "serverGame/ServerResourceClassObject.h"
#include "serverGame/ServerResourceContainerObjectTemplate.h"
#include "serverGame/ServerUniverse.h"
#include "serverGame/ServerWorld.h"
#include "sharedFoundation/ConstCharCrcLowerString.h"
#include "sharedFoundation/DynamicVariableList.h"
#include "sharedGame/SharedObjectAttributes.h"
#include "sharedGame/SharedResourceContainerObjectTemplate.h"
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
#include "sharedObject/ObjectTemplateList.h"
#include "sharedObject/SlottedContainmentProperty.h"
// ======================================================================
const SharedObjectTemplate * ResourceContainerObject::m_defaultSharedTemplate = NULL;
namespace ResourceContainerObjectNamespace
{
const std::string OBJVAR_RESOURCE_DATA("resourceData");
};
using namespace ResourceContainerObjectNamespace;
// ======================================================================
ResourceContainerObject::ResourceContainerObject(const ServerResourceContainerObjectTemplate* newTemplate) :
TangibleObject (newTemplate),
m_resourceType (NetworkId::cms_invalid),
m_quantity (0),
m_source (NetworkId::cms_invalid),
m_maxQuantity (newTemplate->getMaxResources()),
m_resourceName (),
m_parentName ()
{
addMembersToPackages();
}
//-----------------------------------------------------------------------
ResourceContainerObject::~ResourceContainerObject()
{
}
//-----------------------------------------------------------------------
/**
* Returns a shared template if none was given for this object.
*
* @return the shared template
*/
const SharedObjectTemplate * ResourceContainerObject::getDefaultSharedTemplate(void) const
{
static const ConstCharCrcLowerString templateName("object/resource_container/base/shared_resource_container_default.iff");
if (m_defaultSharedTemplate == NULL)
{
m_defaultSharedTemplate = safe_cast<const SharedObjectTemplate *>(ObjectTemplateList::fetch(templateName));
WARNING_STRICT_FATAL(m_defaultSharedTemplate == NULL, ("Cannot create default shared object template %s", templateName.getString()));
if (m_defaultSharedTemplate != NULL)
ExitChain::add (removeDefaultTemplate, "ResourceContainerObject::removeDefaultTemplate");
}
return m_defaultSharedTemplate;
} // ResourceContainerObject::getDefaultSharedTemplate
//-----------------------------------------------------------------------
/**
* Cleans up the default shared template.
*/
void ResourceContainerObject::removeDefaultTemplate(void)
{
if (m_defaultSharedTemplate != NULL)
{
m_defaultSharedTemplate->releaseReference();
m_defaultSharedTemplate = NULL;
}
} // ResourceContainerObject::removeDefaultTemplate
//-----------------------------------------------------------------------
/**
* Creates a default controller for this object.
*
* @return the object's controller
*/
Controller* ResourceContainerObject::createDefaultController(void)
{
Controller* _controller = new ResourceContainerController(this);
NOT_NULL(_controller);
setController(_controller);
return _controller;
} // ResourceContainerObject::createDefaultController
// ----------------------------------------------------------------------
bool ResourceContainerObject::addResource(ResourceTypeObject const * const resourceType, int amount, NetworkId const & sourcePlayer)
{
if (!resourceType)
return false;
return addResource(resourceType->getNetworkId(), amount, sourcePlayer);
}
// ----------------------------------------------------------------------
bool ResourceContainerObject::addResource(const NetworkId &resourceType, int amount, const NetworkId &sourcePlayer)
{
if (amount <= 0)
{
WARNING_STRICT_FATAL(amount<0,("Use removeResource to remove resources from a ResourceContainer.\n"));
return amount == 0;
}
if (isAuthoritative())
{
if (m_quantity.get() + amount > m_maxQuantity.get())
return false; // too much
if (m_quantity.get()==0)
{
// need to set the resource attribute objvar for imported resource type
if (resourceType.getValue() > NetworkId::cms_maxNetworkIdWithoutClusterId)
{
DynamicVariableList const & objvars = getObjVars();
if (!objvars.hasItem(OBJVAR_RESOURCE_DATA) || (DynamicVariable::STRING != objvars.getType(OBJVAR_RESOURCE_DATA)))
{
ResourceTypeObject const * const rto = ServerUniverse::getInstance().getImportedResourceTypeById(resourceType);
if (!rto)
return false;
std::string const resourceData = rto->getResourceTypeDataForExport();
if (resourceData.empty())
return false;
removeObjVarItem(OBJVAR_RESOURCE_DATA);
IGNORE_RETURN(setObjVarItem(OBJVAR_RESOURCE_DATA, resourceData));
}
}
m_resourceType = resourceType; // note that m_quantity should be 0 only if this is a brand new crate
m_source = sourcePlayer;
updateResourceNames();
}
else if (resourceType != m_resourceType.get())
return false; // can't contain two different kinds of resource
m_quantity=m_quantity.get() + amount;
if (sourcePlayer!=NetworkId::cms_invalid)
addResourceSource(sourcePlayer, amount);
setAttributeRevisionDirty();
return true;
}
else
{
WARNING_STRICT_FATAL(true,("Cross-server container transfers are not supported.\n"));
return false;
}
}
// ----------------------------------------------------------------------
bool ResourceContainerObject::removeResource(const NetworkId &resourceType, int amount, std::vector<std::pair<NetworkId, int> > *sources)
{
while (amount > 0)
{
int actualAmountRemoved;
NetworkId source(NetworkId::cms_invalid);
if (!internalRemoveResource(resourceType, amount, source, actualAmountRemoved))
return false;
amount -= actualAmountRemoved;
if (sources)
{
sources->push_back(std::pair<NetworkId, int>(source, actualAmountRemoved));
}
}
return true;
}
/**
* Remove up to a certain amount of resource. The resource removed will
* always be from a single source player. It may be necessary to call this
* function more than once to extract the total amount desired.
*
* @param resourceType The type of resource desired
* @param amount The maximum amount to remove
* @param source (output) Which player the resource came from (can be cms_invalid)
* @param amountRemoved (output) The actual amount removed. Will be <= amount
* @return True if at least 1 unit of the specified resource is removed
*/
bool ResourceContainerObject::internalRemoveResource(const NetworkId &resourceType, int amount, NetworkId &source, int &amountRemoved)
{
if (amount <= 0)
{
WARNING_STRICT_FATAL(amount<0,("Trying to make a deposit with a withdrawal slip. (Called removeResource with a negative amount.)\n"));
return amount == 0;
}
if (isAuthoritative())
{
if (resourceType!=m_resourceType.get())
return false; // wrong kind of resource
amountRemoved = std::min(m_quantity.get(), amount);
// Identify source (if possible)
if (m_source.get() == NetworkId::cms_invalid)
{
// multi-source container. Complicated
source = NetworkId::cms_invalid;
DynamicVariableList::NestedList varList(getObjVars(),"source");
DynamicVariableList::NestedList::const_iterator var(varList.begin());
if (var!=varList.end())
{
int varInt;
if (var.getValue(varInt))
{
amountRemoved = std::min(amountRemoved, varInt);
int remainingAmountFromSource = varInt - amountRemoved;
source = NetworkId(var.getName());
if (remainingAmountFromSource > 0)
{
IGNORE_RETURN(setObjVarItem(var.getNameWithPath(), remainingAmountFromSource));
}
else
removeObjVarItem(var.getNameWithPath());
}
}
}
else
{
// single-source container. Simple
source = m_source.get();
}
// Adjust the quantity remaining
m_quantity=m_quantity.get() - amountRemoved;
if (m_quantity.get() == 0)
IGNORE_RETURN(permanentlyDestroy(DeleteReasons::Consumed)); // containers delete themselves when empty
setAttributeRevisionDirty();
return true;
}
else
{
WARNING_STRICT_FATAL(true,("Cross-server container transfers are not supported.\n"));
return false;
}
}
// ----------------------------------------------------------------------
std::string ResourceContainerObject::getResourceCtsData() const
{
// resource came from another galaxy, so all the data is stored in the objvar
DynamicVariableList const & objvars = getObjVars();
if (objvars.hasItem(OBJVAR_RESOURCE_DATA) && (DynamicVariable::STRING == objvars.getType(OBJVAR_RESOURCE_DATA)))
{
std::string resourceData;
IGNORE_RETURN(objvars.getItem(OBJVAR_RESOURCE_DATA, resourceData));
return resourceData;
}
// resource came from this cluster, so construct the resource data
else
{
ResourceTypeObject const * const typeObj = getResourceType();
if (typeObj)
return typeObj->getResourceTypeDataForExport();
return std::string();
}
}
// ----------------------------------------------------------------------
void ResourceContainerObject::setResourceCtsData(int quantity, const std::string & resourceData)
{
if (!isAuthoritative())
return;
if (m_resourceType.get().isValid())
return;
if (m_quantity.get() > 0)
return;
if (quantity <= 0)
return;
if (resourceData.empty())
return;
removeObjVarItem(OBJVAR_RESOURCE_DATA);
NetworkId const importedResourceType = ResourceTypeObject::addImportedResourceType(resourceData);
if (importedResourceType.isValid())
{
if (importedResourceType.getValue() > NetworkId::cms_maxNetworkIdWithoutClusterId)
{
// need to tell all proxy game servers, if any, to create the imported
// resource type, if it hasn't already been created on that game server
ProxyList const &proxyList = getExposedProxyList();
if (!proxyList.empty())
{
ServerMessageForwarding::begin(std::vector<uint32>(proxyList.begin(), proxyList.end()));
GenericValueTypeMessage<std::pair<NetworkId, std::string> > const addImportedResourceTypeMsg("AddImportedResourceType", std::make_pair(importedResourceType, resourceData));
ServerMessageForwarding::send(addImportedResourceTypeMsg);
ServerMessageForwarding::end();
}
}
IGNORE_RETURN(!addResource(importedResourceType, quantity, NetworkId::cms_invalid));
}
if (!getObjVars().hasItem(OBJVAR_RESOURCE_DATA))
{
if (!m_resourceType.get().isValid() || (m_resourceType.get().getValue() > NetworkId::cms_maxNetworkIdWithoutClusterId))
IGNORE_RETURN(setObjVarItem(OBJVAR_RESOURCE_DATA, resourceData));
}
}
// ----------------------------------------------------------------------
std::string ResourceContainerObject::debugPrint() const
{
char buffer[20];
IGNORE_RETURN(snprintf(buffer, 20, "%i",m_quantity.get()));
ResourceTypeObject const * const r=ServerUniverse::getInstance().getResourceTypeById(m_resourceType.get());
if (r)
return (std::string("Resource Container with ")+buffer+" units of "+r->getResourceName());
else
return ("Invalid resource container");
}
// ----------------------------------------------------------------------
/**
* Transfer resources from one container to another.
* @return true if all the resource was tranferred, false if no resources
* or less than the requested amount was transferred.
* @todo Inter-server authority issues
*/
bool ResourceContainerObject::transferTo(ResourceContainerObject &destination, int amount)
{
if (isAuthoritative())
{
if ((m_resourceType.get() != destination.m_resourceType.get() && (destination.m_resourceType.get() != NetworkId::cms_invalid))
|| amount > m_quantity.get())
return false;
NetworkId sourcePlayer(NetworkId::cms_invalid);
int amountRemoved = 0;
while (amount > 0)
{
if (!internalRemoveResource(m_resourceType.get(), amount, sourcePlayer, amountRemoved))
return false;
if (!destination.addResource(m_resourceType.get(), amountRemoved, sourcePlayer))
{
// failed to add resource to destination, put it back into the source
IGNORE_RETURN(addResource(m_resourceType.get(), amountRemoved, sourcePlayer));
return false;
}
amount -= amountRemoved;
}
return true;
}
else
{
WARNING_STRICT_FATAL(true,("Cross-server container transfers are not supported.\n"));
return false;
}
}
// ----------------------------------------------------------------------
/**
* Split this container into two containers
* @param amount The amount to put in the new ResourceContainer
* @param destContainer The container into which the new ResourceContainer should be placed, or cms_Invalid if no container
* @param arrangementId -1 If destContainer is not slotted, otherwise the ID of the arrangement to use
* @param newLocation The coordinates at which to place the new ResourceContainer. (Ignored if it is going into a non-positional container.)
* @param actor The player making the split, or NULL
*/
bool ResourceContainerObject::splitContainer(int amount, const CachedNetworkId &destContainer, int arrangementId, const Vector &newLocation, ServerObject *actor)
{
UNREF(actor);
bool result = false;
ResourceContainerObject *newCrate = NULL;
if (destContainer == CachedNetworkId::cms_cachedInvalid)
{
// create in world
Transform tr;
tr.setPosition_p(newLocation);
newCrate = dynamic_cast<ResourceContainerObject*>(ServerWorld::createNewObject(getObjectTemplateName(), tr, 0, isPersisted()));
}
else if (arrangementId < 0)
{
// create in volume container
ServerObject * destObject = safe_cast<ServerObject *>(destContainer.getObject());
if (destObject == NULL)
return false;
newCrate = dynamic_cast<ResourceContainerObject*>(ServerWorld::createNewObject(getObjectTemplateName(), *destObject, isPersisted()));
}
else
{
// create in slotted container
ServerObject * destObject = safe_cast<ServerObject *>(destContainer.getObject());
if (destObject == NULL)
return false;
const SlottedContainmentProperty* containmentProperty = ContainerInterface::getSlottedContainmentProperty(*destObject);
if (containmentProperty == NULL)
return false;
const SlottedContainmentProperty::SlotArrangement & slots = containmentProperty->getSlotArrangement(arrangementId);
if (slots.empty())
return false;
newCrate = dynamic_cast<ResourceContainerObject*>(ServerWorld::createNewObject(getObjectTemplateName(), *destObject, slots.front(), isPersisted()));
}
if (newCrate)
{
result = transferTo(*newCrate, amount);
if (!result)
IGNORE_RETURN(newCrate->permanentlyDestroy(DeleteReasons::BadContainerTransfer));
}
return result;
}
//----------------------------------------------------------------------
void ResourceContainerObject::updateResourceNames()
{
if (!isAuthoritative())
return;
m_resourceName.set (Unicode::emptyString);
m_parentName.set (std::string ());
m_resourceNameId.set (StringId::cms_invalid);
setAttributeRevisionDirty();
if (!m_resourceType.get ().isValid ())
{
setObjectName (Unicode::emptyString);
return;
}
//-- setup the parent inheritance chain.
//-- the client needs this information
ResourceTypeObject const * const type = ServerUniverse::getInstance().getResourceTypeById(m_resourceType.get());
if (type)
{
m_resourceName = Unicode::narrowToWide(type->getResourceName ());
if ((m_resourceName.get())[0] == '@')
{
m_resourceNameId = StringId(Unicode::wideToNarrow(m_resourceName.get()));
}
ResourceClassObject const & parentClass = type->getParentClass();
m_parentName = parentClass.getResourceClassName ();
ResourceClassObject const * const parentClass2 = parentClass.getParent ();
if (parentClass2)
{
setObjectName(Unicode::emptyString);
setObjectNameStringId (parentClass2->getFriendlyName());
}
else
{
setObjectName(Unicode::emptyString);
setObjectNameStringId (parentClass.getFriendlyName());
}
}
else
DEBUG_WARNING (true, ("Unable to find specified resource type %s", m_resourceType.get ().getValueString ().c_str ()));
}
// ----------------------------------------------------------------------
std::string ResourceContainerObject::getItemLog() const
{
char tmpBuffer[1024];
IGNORE_RETURN(snprintf(tmpBuffer, sizeof(tmpBuffer) - 1, ": %d units of %s", getQuantity(), Unicode::wideToNarrow(m_resourceName.get()).c_str()));
tmpBuffer[sizeof(tmpBuffer)-1] = 0;
return TangibleObject::getItemLog() + tmpBuffer;
}
// ----------------------------------------------------------------------
void ResourceContainerObject::getAttributes(stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const
{
TangibleObject::getAttributes(data);
char valueBuffer[32];
IGNORE_RETURN(snprintf (valueBuffer, sizeof (valueBuffer), "%d/%d", getQuantity (), getMaxQuantity ()));
data.push_back (std::make_pair (SharedObjectAttributes::resource_contents, Unicode::narrowToWide (valueBuffer)));
ResourceTypeObject const * const typeObj = getResourceType();
if (typeObj)
{
data.push_back (std::make_pair (SharedObjectAttributes::resource_name, Unicode::narrowToWide(typeObj->getResourceName ())));
ResourceClassObject const & parent = typeObj->getParentClass ();
data.push_back (std::make_pair (SharedObjectAttributes::resource_class, Unicode::narrowToWide ("@" + parent.getFriendlyName ().getCanonicalRepresentation())));
typeObj->getResourceAttributes(data);
}
}
// ----------------------------------------------------------------------
void ResourceContainerObject::endBaselines()
{
TangibleObject::endBaselines();
if (isAuthoritative())
{
// if resource is an imported resource, register the imported resource type on
// this game server, if it hasn't already been registered on this game server;
// this must be done on each game server as it receives the resource container
DynamicVariableList const & objvars = getObjVars();
if (objvars.hasItem(OBJVAR_RESOURCE_DATA) && (DynamicVariable::STRING == objvars.getType(OBJVAR_RESOURCE_DATA)))
{
bool const alreadyRegistered = (m_resourceType.get().isValid() && (m_resourceType.get().getValue() > NetworkId::cms_maxNetworkIdWithoutClusterId) && ServerUniverse::getInstance().getImportedResourceTypeById(m_resourceType.get()));
if (!alreadyRegistered)
{
std::string resourceData;
IGNORE_RETURN(objvars.getItem(OBJVAR_RESOURCE_DATA, resourceData));
NetworkId const importedResourceType = ResourceTypeObject::addImportedResourceType(resourceData);
if (importedResourceType.isValid())
{
if (importedResourceType != m_resourceType.get())
m_resourceType = importedResourceType;
if (importedResourceType.getValue() <= NetworkId::cms_maxNetworkIdWithoutClusterId)
removeObjVarItem(OBJVAR_RESOURCE_DATA);
}
}
}
updateResourceNames();
}
else
{
// if resource is an imported resource, register the imported resource type on
// this game server, if it hasn't already been registered on this game server;
// this must be done on each game server as it receives the resource container
if (m_resourceType.get().isValid() && (m_resourceType.get().getValue() > NetworkId::cms_maxNetworkIdWithoutClusterId) && !ServerUniverse::getInstance().getImportedResourceTypeById(m_resourceType.get()))
{
DynamicVariableList const & objvars = getObjVars();
if (objvars.hasItem(OBJVAR_RESOURCE_DATA) && (DynamicVariable::STRING == objvars.getType(OBJVAR_RESOURCE_DATA)))
{
std::string resourceData;
IGNORE_RETURN(objvars.getItem(OBJVAR_RESOURCE_DATA, resourceData));
IGNORE_RETURN(ResourceTypeObject::addImportedResourceType(resourceData));
}
}
}
}
// ----------------------------------------------------------------------
void ResourceContainerObject::addResourceSource(const NetworkId &source, int amount)
{
if (source == m_source.get())
return; // single-source container adding more resource from the same source -- no change needed
if (m_source.get() != NetworkId::cms_invalid)
{
// converting a single-source container into a multi-source container. All resources except the ones from the new source get credited to the first source
const std::string & varname = std::string("source.") + m_source.get().getValueString();
IGNORE_RETURN(setObjVarItem(varname, m_quantity.get() - amount));
m_source = NetworkId::cms_invalid;
}
const std::string & varname = std::string("source.") + source.getValueString ();
int intvar = 0;
if (getObjVars().getItem(varname,intvar))
{
IGNORE_RETURN(setObjVarItem(varname, intvar+amount));
}
else
{
removeObjVarItem(varname);
IGNORE_RETURN(setObjVarItem(varname, amount));
}
}
// ----------------------------------------------------------------------
bool ResourceContainerObject::removeResourceWithoutExperience(const NetworkId &resourceType, int amount)
{
while (amount > 0)
{
int amountRemoved = 0;
NetworkId source;
if (!internalRemoveResource(resourceType, amount, source, amountRemoved))
return false;
amount -= amountRemoved;
}
return true;
}
// ----------------------------------------------------------------------
ResourceTypeObject const * const ResourceContainerObject::getResourceType() const
{
return ServerUniverse::getInstance().getResourceTypeById(m_resourceType.get());
}
// ----------------------------------------------------------------------
NetworkId ResourceContainerObject::getResourceTypeId() const
{
return m_resourceType.get();
}
// ----------------------------------------------------------------------
/**
* For debugging only, convert this container to the recycled equivalent.
* This is not intended for uses other than debugging, because the container
* might not be the right kind of container to hold the recycled resource
*/
bool ResourceContainerObject::debugRecycle()
{
if (!isAuthoritative())
return false;
ResourceTypeObject const * const resourceType=getResourceType();
if (!resourceType)
return false;
if (resourceType->isRecycled())
return true; // already recycled
ResourceTypeObject const * const recycledType=resourceType->getRecycledVersion();
if (!recycledType)
return false; // no recycled version of this resource
DEBUG_FATAL(recycledType == resourceType,("Programmer bug: resourceType->getRecycledVersion on %s returned the same type.",resourceType->getResourceName().c_str()));
m_resourceType = recycledType->getNetworkId();
updateResourceNames();
return true;
}
// ======================================================================
@@ -0,0 +1,101 @@
//========================================================================
//
// ResourceContainerObject.h
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#ifndef _INCLUDED_ResourceContainerObject_H
#define _INCLUDED_ResourceContainerObject_H
#include "serverGame/TangibleObject.h"
class ResourceTypeObject;
class ServerResourceContainerObjectTemplate;
// ======================================================================
class ResourceContainerObject : public TangibleObject
{
public:
ResourceContainerObject(const ServerResourceContainerObjectTemplate* newTemplate);
virtual ~ResourceContainerObject();
static void removeDefaultTemplate(void);
virtual Controller* createDefaultController(void);
// Container transfers
bool addResource (const NetworkId &resourceType, int amount, const NetworkId &sourcePlayer);
bool addResource (ResourceTypeObject const * const resourceType, int amount, NetworkId const & sourcePlayer);
bool removeResource (const NetworkId &resourceType, int amount, stdvector<std::pair<NetworkId, int> >::fwd *sources);
bool removeResourceWithoutExperience(const NetworkId &resourceType, int amount); //TODO: rewrite crafting to handle experience, remove this function
bool transferTo (ResourceContainerObject &destination, int amount);
bool splitContainer (int amount, const CachedNetworkId &destContainer, int arrangementId, const Vector &newLocation, ServerObject *actor);
bool debugRecycle ();
ResourceTypeObject const * const getResourceType () const;
NetworkId getResourceTypeId () const;
int getQuantity () const;
int getMaxQuantity () const;
std::string getResourceCtsData() const;
void setResourceCtsData(int quantity, const std::string & resourceData);
std::string debugPrint () const;
virtual void getAttributes (stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const;
virtual void endBaselines ();
virtual std::string getItemLog() const;
protected:
virtual const SharedObjectTemplate * getDefaultSharedTemplate(void) const;
private:
void addResourceSource(const NetworkId &source, int amount);
bool transferHelper (ResourceContainerObject &destination, int amount, const NetworkId &resourceSourcePlayer);
bool internalRemoveResource (const NetworkId &resourceType, int amount, NetworkId &source, int &amountRemoved);
private:
ResourceContainerObject();
ResourceContainerObject(const ResourceContainerObject& rhs);
ResourceContainerObject& operator=(const ResourceContainerObject& rhs);
private:
void addMembersToPackages();
void updateResourceNames ();
static const SharedObjectTemplate * m_defaultSharedTemplate; // template to use if no shared template is given
// persisted
Archive::AutoDeltaVariable<NetworkId> m_resourceType;
Archive::AutoDeltaVariable<int> m_quantity;
Archive::AutoDeltaVariable<NetworkId> m_source;
//non-persisted
Archive::AutoDeltaVariable<int> m_maxQuantity;
Archive::AutoDeltaVariable<Unicode::String> m_resourceName;
Archive::AutoDeltaVariable<std::string> m_parentName;
Archive::AutoDeltaVariable<StringId> m_resourceNameId;
};
// ----------------------------------------------------------------------
inline int ResourceContainerObject::getQuantity() const
{
return m_quantity.get();
}
// ----------------------------------------------------------------------
inline int ResourceContainerObject::getMaxQuantity() const
{
return m_maxQuantity.get();
}
// ======================================================================
#endif // _INCLUDED_ResourceContainerObject_H
@@ -0,0 +1,135 @@
//========================================================================
//
// ResourcePoolObject.cpp
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/ResourcePoolObject.h"
#include "UnicodeUtils.h"
#include "serverGame/ConfigServerGame.h"
#include "serverGame/MessageToQueue.h"
#include "serverGame/PlanetObject.h"
#include "serverGame/ResourceTypeObject.h"
#include "serverGame/ServerWorld.h"
#include "serverGame/ServerUniverse.h"
#include "serverUtility/ServerClock.h"
#include "sharedFoundation/DynamicVariableList.h"
#include "sharedFractal/MultiFractal.h"
#include <stdio.h>
// ----------------------------------------------------------------------
ResourcePoolObject::ResourcePoolObject(ResourceTypeObject const & resourceType, PlanetObject const & planetObject, uint32 fractalSeed) :
m_resourceType(resourceType),
m_planet(planetObject),
m_fractalData(resourceType.getFractalData()),
m_fractalSeed(fractalSeed),
m_depletedTimestamp(resourceType.getDepletedTimestamp()),
m_efficiencyMap(NULL)
{
}
//-----------------------------------------------------------------------
ResourcePoolObject::~ResourcePoolObject()
{
delete m_efficiencyMap;
m_efficiencyMap=NULL;
}
// ----------------------------------------------------------------------
/**
* Called to harvest resources from the pool.
* @param lastHarvestTick Tick count the last time this harvester
* harvested from the pool.
* @param installedEfficiency The value returned by placeHarvester() when
* the harvester was placed.
* @param harvesterId The objectID of the harvester collecting the resource.
*/
float ResourcePoolObject::harvest(float installedEfficiency, uint32 lastHarvestTime) const
{
int elapsedTime=static_cast<int>(std::min(ServerClock::getInstance().getGameTimeSeconds(),m_depletedTimestamp) - lastHarvestTime);
if (elapsedTime < 0)
return 0;
float elapsedTicks =static_cast<float>(elapsedTime) / static_cast<float>(ConfigServerGame::getSecondsPerResourceTick());
float amountHarvested = elapsedTicks * installedEfficiency;
return amountHarvested;
}
// ----------------------------------------------------------------------
/**
* Get the value of the efficiency map at a specific location.
*/
float ResourcePoolObject::getEfficiencyAtLocation(float x, float z) const
{
if (!m_efficiencyMap)
{
m_efficiencyMap = new MultiFractal;
m_efficiencyMap->setSeed(m_fractalSeed);
m_efficiencyMap->setScale(m_fractalData.m_scaleX, m_fractalData.m_scaleY);
m_efficiencyMap->setBias(true,m_fractalData.m_bias);
m_efficiencyMap->setGain(true,m_fractalData.m_gain);
m_efficiencyMap->setCombinationRule(static_cast<MultiFractal::CombinationRule>(m_fractalData.m_combinationRule));
m_efficiencyMap->setFrequency(m_fractalData.m_frequency);
m_efficiencyMap->setAmplitude(m_fractalData.m_amplitude);
m_efficiencyMap->setNumberOfOctaves(m_fractalData.m_octaves);
}
return m_efficiencyMap->getValue(x,z);
}
// ----------------------------------------------------------------------
void ResourcePoolObject::debugOutput(Unicode::String &output) const
{
char buffer[256];
sprintf(buffer,"Pool of %s: ",m_resourceType.getNetworkId().getValueString().c_str());
output+=Unicode::narrowToWide(buffer)+Unicode::narrowToWide(m_resourceType.getResourceName());
if (isDepleted())
output+=Unicode::narrowToWide(" DEPLETED");
else
{
sprintf(buffer," %lu time units left\n",(m_depletedTimestamp - ServerClock::getInstance().getGameTimeSeconds())/ConfigServerGame::getResourceTimeScale());
output+=Unicode::narrowToWide(buffer);
}
}
// ----------------------------------------------------------------------
/**
* Extract resource from the pool once only. To avoid requiring a callback,
* this function will allow you to harvest from a proxy object, possibly
* giving you a little more than you could normally get if the pool is
* almost depleted.
* @param amount Maximum amount to harvest.
* @location Point to use for the effeciency calculation.
* @return Amount of resource you receive.
*/
int ResourcePoolObject::oneTimeHarvest(int amount, const Vector & location) const
{
if (isDepleted())
return 0;
int result = static_cast<int>(static_cast<float>(amount) * getEfficiencyAtLocation(location.x, location.z));
return result;
}
// ----------------------------------------------------------------------
bool ResourcePoolObject::isDepleted() const
{
return m_resourceType.isDepleted();
}
// ======================================================================
@@ -0,0 +1,75 @@
//========================================================================
//
// ResourcePoolObject.h
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#ifndef INCLUDED_ResourcePoolObject_H
#define INCLUDED_ResourcePoolObject_H
#include "serverGame/UniverseObject.h"
#include "sharedObject/CachedNetworkId.h"
class DynamicVariableList;
class MultiFractal;
class PlanetObject;
class ResourceTypeObject;
struct ResourceFractalData;
// ======================================================================
/**
* A pool of a resource found on a planet.
*
* Represents the planet's supply of a particular resource.
*/
class ResourcePoolObject
{
public:
// getter functions
ResourceTypeObject const & getResourceType () const;
bool isDepleted () const;
float getEfficiencyAtLocation (float x, float z) const;
CachedNetworkId const & getPlanet () const;
void debugOutput (Unicode::String &output) const;
// simulation functions
float harvest (float installedEfficiency, uint32 lastHarvestTick) const;
int oneTimeHarvest (int amount, const Vector &location) const;
ResourcePoolObject(ResourceTypeObject const & resourceType, PlanetObject const & planetObject, uint32 fractalSeed);
virtual ~ResourcePoolObject();
private:
ResourcePoolObject(const ResourcePoolObject& rhs);
ResourcePoolObject& operator=(const ResourcePoolObject& rhs);
private:
ResourceTypeObject const & m_resourceType;
CachedNetworkId const m_planet;
ResourceFractalData const & m_fractalData;
uint32 const m_fractalSeed;
uint32 m_depletedTimestamp;
MultiFractal mutable * m_efficiencyMap;
};
// ======================================================================
inline ResourceTypeObject const & ResourcePoolObject::getResourceType() const
{
return m_resourceType;
}
// ----------------------------------------------------------------------
inline CachedNetworkId const & ResourcePoolObject::getPlanet() const
{
return m_planet;
}
// ======================================================================
#endif
@@ -0,0 +1,547 @@
//========================================================================
//
// ResourceTypeObject.cpp
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/ResourceTypeObject.h"
#include "UnicodeUtils.h"
#include "serverGame/ConfigServerGame.h"
#include "serverGame/GameServer.h"
#include "serverGame/ObjectIdManager.h"
#include "serverGame/PlanetObject.h"
#include "serverGame/ResourcePoolObject.h"
#include "serverGame/ServerResourceClassObject.h"
#include "serverGame/ServerUniverse.h"
#include "serverNetworkMessages/AddResourceTypeMessage.h"
#include "serverUtility/ServerClock.h"
#include "sharedFoundation/FormattedString.h"
#include "sharedLog/Log.h"
#include "sharedObject/NetworkIdManager.h"
#include "sharedRandom/Random.h"
#include <map>
#include <cstdio>
#include <vector>
// ======================================================================
/**
* Constructor to spawn a new resource type from the specified class
*/
ResourceTypeObject::ResourceTypeObject(ServerResourceClassObject & parent) :
m_networkId(ObjectIdManager::getNewObjectId()),
m_resourceName((parent.isRecycled() || parent.isPermanent()) ? "@" + parent.getFriendlyName().getCanonicalRepresentation() : ServerUniverse::getInstance().generateRandomResourceName(parent.getNameTable())),
m_resourceClass(parent),
m_attributes(),
m_fractalData(parent.getFractalData()),
m_fractalSeeds(),
m_depletedTimestamp((parent.isRecycled() || parent.isPermanent()) ? ServerClock::cms_endOfTime : ServerClock::getInstance().getGameTimeSeconds() + static_cast<uint32>(Random::random(parent.getMinPoolSize(),parent.getMaxPoolSize())) * ConfigServerGame::getResourceTimeScale()),
m_pools()
{
LOG("CustomerService",("Resource Type %s spawned from class %s",getResourceName().c_str(),m_resourceClass.getResourceClassName().c_str()));
rollAttributes();
if (!parent.isRecycled() && !parent.isPermanent())
{
// Pick planets and fractal seeds
std::vector<std::string> possiblePlanets = parent.getPossiblePlanets();
for (int numPools = Random::random(parent.getMinPools(), parent.getMaxPools()); numPools > 0; --numPools)
{
if (possiblePlanets.size()==0)
{
WARNING_STRICT_FATAL(true,("Needed to spawn pool for resource %s (%s), but there were no possible planets remaining.",m_resourceName.c_str(), parent.getResourceClassName().c_str()));
break;
}
size_t const choiceIndex = static_cast<size_t>(Random::random(0,static_cast<int>(possiblePlanets.size())-1));
PlanetObject const * const planet = ServerUniverse::getInstance().getPlanetByName(possiblePlanets[choiceIndex]);
if (!planet)
WARNING_STRICT_FATAL(true,("Resource type %s specified planet %s, which could not be found\n",
getNetworkId().getValueString().c_str(),possiblePlanets[choiceIndex].c_str()));
else
{
IGNORE_RETURN(m_fractalSeeds.insert(std::make_pair(planet->getNetworkId(), Random::random()))); //lint !e1025 !e1703 // lint can't parse this for some reason
LOG("CustomerService",("Resource Pool of %s (class %s) spawned on %s",
getResourceName().c_str(),m_resourceClass.getResourceClassName().c_str(),possiblePlanets[choiceIndex].c_str()));
possiblePlanets[choiceIndex] = possiblePlanets.back();
possiblePlanets.pop_back();
}
}
}
}
//-----------------------------------------------------------------------
ResourceTypeObject::~ResourceTypeObject()
{
}
// ----------------------------------------------------------------------
void ResourceTypeObject::debugOutput(std::string &output, int numSpaces) const
{
char buffer[30];
sprintf(buffer,"%s",getNetworkId().getValueString().c_str());
{
for (int i=0; i<numSpaces; ++i)
{
output+=" ";
}
}
output+=buffer;
output+=": ";
output+=getResourceName();
output+=" ";
if (!isDepleted())
{
output+=ServerClock::getInstance().getDebugPrintableTimeframe(m_depletedTimestamp - ServerClock::getInstance().getGameTimeSeconds());
output+=" remaining";
}
else
output+="depleted";
output+=" (";
{
for (FractalSeedsType::const_iterator i=m_fractalSeeds.begin(); i!=m_fractalSeeds.end(); )
{
PlanetObject const * const planet = safe_cast<PlanetObject const *>(NetworkIdManager::getObjectById(i->first));
if (planet)
{
output += planet->getName();
}
if (++i != m_fractalSeeds.end())
output += ',';
}
}
output+=")\n";
}
// ----------------------------------------------------------------------
/**
* Change a resource name (console/god command)
*/
void ResourceTypeObject::setName(const std::string &newName)
{
if (ServerUniverse::getInstance().isAuthoritative())
{
ServerUniverse::getInstance().renameResourceType(m_resourceName,newName);
m_resourceName=newName;
ServerUniverse::getInstance().sendUpdatedTypeToAllServers(*this);
}
}
// ----------------------------------------------------------------------
ResourcePoolObject *ResourceTypeObject::getPoolForPlanet(PlanetObject const &planetObject) const
{
if (isRecycled())
return NULL;
std::map<NetworkId, ResourcePoolObject*>::const_iterator i=m_pools.find(planetObject.getNetworkId());
if (i==m_pools.end())
{
FractalSeedsType::const_iterator seed = m_fractalSeeds.find(planetObject.getNetworkId());
if (seed != m_fractalSeeds.end())
{
// create the object for the pool the first time someone needs it
ResourcePoolObject *obj = new ResourcePoolObject(*this, planetObject, seed->second);
m_pools[planetObject.getNetworkId()]=obj;
return obj;
}
else
{
if (ConfigServerGame::getSpawnAllResources())
{
ResourcePoolObject *obj = new ResourcePoolObject(*this, planetObject, 0);
m_pools[planetObject.getNetworkId()]=obj;
return obj;
}
return NULL; // no pool for this planet
}
}
else
return i->second;
}
// ----------------------------------------------------------------------
bool ResourceTypeObject::hasPoolForPlanet (const NetworkId &planet) const
{
return (!isDepleted()) && (m_fractalSeeds.find(planet) != m_fractalSeeds.end());
}
// ----------------------------------------------------------------------
ServerResourceClassObject const & ResourceTypeObject::getParentClass() const
{
return m_resourceClass; // lint !e1536 // exposing "low access member" -- Lint thinks we're returning a reference to m_resouceClass itself, but we're actually returning a reference to the thing m_resourceClass refers to
}
// ----------------------------------------------------------------------
bool ResourceTypeObject::isDepleted() const
{
return (m_depletedTimestamp <= ServerClock::getInstance().getGameTimeSeconds());
}
// ----------------------------------------------------------------------
/**
* Returns the number of non-depleted pools of this resource.
*/
int ResourceTypeObject::getNumPools() const
{
return isDepleted() ? 0 : static_cast<int>(m_fractalSeeds.size());
}
// ----------------------------------------------------------------------
/**
* Returns true if this ResourceType is derived (directly or indirectly) from the class.
*/
bool ResourceTypeObject::isDerivedFrom(const ResourceClassObject &masterClass) const
{
return m_resourceClass.isDerivedFrom(masterClass);
}
// ----------------------------------------------------------------------
/**
* Returns the template name for the appropriate kind of crate to use for this resource.
*/
void ResourceTypeObject::getCrateTemplate(std::string &buffer) const
{
m_resourceClass.getCrateTemplate(buffer);
}
// ----------------------------------------------------------------------
/**
* Get only those attributes specific to the resource
*/
void ResourceTypeObject::getResourceAttributes (stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const
{
for (AttributesType::const_iterator i=m_attributes.begin(); i!=m_attributes.end(); ++i)
{
char buffer[300];
sprintf(buffer,"%i",i->second);
data.push_back(std::pair<std::string, Unicode::String>(i->first,Unicode::narrowToWide(buffer)));
}
}
// ----------------------------------------------------------------------
std::string const & ResourceTypeObject::getResourceName() const
{
static std::string const unnamed("unnamed");
if (isNamed())
return m_resourceName;
else
return unnamed;
}
// ----------------------------------------------------------------------
/**
* Force this resource type to be depleted.
* (Console/God command)
*/
void ResourceTypeObject::deplete()
{
DEBUG_FATAL(!ServerUniverse::getInstance().isAuthoritative(),("Programmer bug: ResourceTypeObject::deplete() should only be called on the authoritative server. Use ServerUniverse::manualDepleteResource() instead."));
if (ServerUniverse::getInstance().isAuthoritative())
{
m_depletedTimestamp = ServerClock::getInstance().getGameTimeSeconds();
ServerUniverse::getInstance().sendUpdatedTypeToAllServers(*this);
}
}
// ----------------------------------------------------------------------
ResourcePoolObject * ResourceTypeObject::getPoolForCurrentPlanet() const
{
return getPoolForPlanet(*(NON_NULL(ServerUniverse::getInstance().getCurrentPlanet())));
}
// ----------------------------------------------------------------------
ResourceFractalData const & ResourceTypeObject::getFractalData() const
{
return m_fractalData;
}
// ----------------------------------------------------------------------
NetworkId const & ResourceTypeObject::getNetworkId() const
{
return m_networkId;
}
// ----------------------------------------------------------------------
uint32 ResourceTypeObject::getDepletedTimestamp() const
{
return m_depletedTimestamp;
}
// ----------------------------------------------------------------------
int ResourceTypeObject::getAttribute(std::string const & attributeName) const
{
AttributesType::const_iterator i=m_attributes.find(attributeName);
if (i==m_attributes.end())
return -1;
else
return i->second;
}
// ----------------------------------------------------------------------
/**
* Pack this resource type into a AddResourceTypeMessageNamespace::ResourceTypeData,
* which can be used to send it on the network.
*/
void ResourceTypeObject::getDataForMessage(AddResourceTypeMessageNamespace::ResourceTypeData & buffer) const
{
buffer.m_networkId = m_networkId;
buffer.m_name = m_resourceName;
buffer.m_depletedTimestamp = m_depletedTimestamp;
buffer.m_parentClass=m_resourceClass.getResourceClassName();
buffer.m_attributes.clear();
buffer.m_attributes.reserve(m_attributes.size());
{
for(AttributesType::const_iterator i=m_attributes.begin(); i!=m_attributes.end(); ++i)
buffer.m_attributes.push_back(*i); //lint !e1561 // (Reference initialization causes loss of const/volatile integrity (arg. no. 1))
}
buffer.m_fractalSeeds.clear();
buffer.m_fractalSeeds.reserve(m_fractalSeeds.size());
{
for(FractalSeedsType::const_iterator i=m_fractalSeeds.begin(); i!=m_fractalSeeds.end(); ++i)
buffer.m_fractalSeeds.push_back(*i); //lint !e1025 !e1703 // lint can't parse this line
}
}
// ----------------------------------------------------------------------
ResourceTypeObject::ResourceTypeObject(AddResourceTypeMessageNamespace::ResourceTypeData const & data, ServerResourceClassObject & parentClass) :
m_networkId(data.m_networkId),
m_resourceName(data.m_name),
m_resourceClass(parentClass),
m_attributes(),
m_fractalData(parentClass.getFractalData()),
m_fractalSeeds(),
m_depletedTimestamp(data.m_depletedTimestamp),
m_pools()
{
if (getParentClass().isRecycled())
{
// Recalculate recycled resource attributes on every startup, because they may have changed in the data table. Otherwise recycled resource attributes
// could never be changed. (Regular resources that turn over keep their current attributes, even if the data table changes, until they turn over.)
// Since each server does this independantly, recycled resources must have fixed attributes (enforced by rollAttributes()).
rollAttributes();
}
else
{
for(std::vector<std::pair<std::string, int> >::const_iterator i=data.m_attributes.begin(); i!=data.m_attributes.end(); ++i)
IGNORE_RETURN(m_attributes.insert(*i));
}
for(std::vector<std::pair<NetworkId, int> >::const_iterator j=data.m_fractalSeeds.begin(); j!=data.m_fractalSeeds.end(); ++j)
IGNORE_RETURN(m_fractalSeeds.insert(*j)); //lint !e1025 !e1703 // lint can't parse this line
}
// ----------------------------------------------------------------------
ResourceTypeObject const * ResourceTypeObject::getRecycledVersion() const
{
ServerResourceClassObject const * const recycledClass = safe_cast<ServerResourceClassObject const *>(m_resourceClass.getRecycledVersion());
if (recycledClass)
{
ResourceTypeObject const * const result = recycledClass->getAResourceType();
DEBUG_FATAL(!result,("Programmer or Data bug: Recycled class %s had no resource types derived from it. Recycled resources should require 1 resource type be derived from them",recycledClass->getResourceClassName().c_str()));
DEBUG_FATAL(result->isDepleted(),("Programmer bug: recycledClass->getAResourceType() returned a depleted resource. Recycled resources should never be depleted."));
return result;
}
else
return NULL;
}
// ----------------------------------------------------------------------
std::string ResourceTypeObject::getResourceTypeDataForExport() const
{
std::string resourceData;
if (m_networkId.getValue() <= NetworkId::cms_maxNetworkIdWithoutClusterId)
{
resourceData = FormattedString<512>().sprintf("%s~%u~%s~%s~%s", GameServer::getInstance().getClusterName().c_str(), GameServer::getInstance().getClusterId(), getResourceName().c_str(), m_networkId.getValueString().c_str(), m_resourceClass.getResourceClassName().c_str());
for (std::map<std::string, int>::const_iterator iter = m_attributes.begin(); iter != m_attributes.end(); ++iter)
{
resourceData += "~";
resourceData += FormattedString<512>().sprintf("%s %d", iter->first.c_str(), iter->second);
}
return resourceData;
}
std::string const & resourceNameWithCluster = getResourceName();
std::string::size_type const openParenPos = resourceNameWithCluster.find('(');
if (openParenPos != std::string::npos)
{
std::string::size_type const closeParenPos = resourceNameWithCluster.find(')');
if ((closeParenPos != std::string::npos) && ((openParenPos + 1) < closeParenPos) && ((closeParenPos + 1) < resourceNameWithCluster.size()))
{
std::string const clusterName = resourceNameWithCluster.substr((openParenPos + 1), (closeParenPos - openParenPos - 1));
std::string const resourceName = resourceNameWithCluster.substr(closeParenPos + 1);
if (!clusterName.empty() && !resourceName.empty())
{
NetworkId const resourceId = NetworkId(m_networkId.getValueWithoutClusterId());
uint8 const clusterId = m_networkId.getValueClusterId();
if (resourceId.isValid() && (resourceId.getValue() <= NetworkId::cms_maxNetworkIdWithoutClusterId) && (clusterId > 0))
{
resourceData = FormattedString<512>().sprintf("%s~%u~%s~%s~%s", clusterName.c_str(), clusterId, resourceName.c_str(), resourceId.getValueString().c_str(), m_resourceClass.getResourceClassName().c_str());
for (std::map<std::string, int>::const_iterator iter = m_attributes.begin(); iter != m_attributes.end(); ++iter)
{
resourceData += "~";
resourceData += FormattedString<512>().sprintf("%s %d", iter->first.c_str(), iter->second);
}
}
}
}
}
return resourceData;
}
// ----------------------------------------------------------------------
NetworkId ResourceTypeObject::addImportedResourceType(std::string const & resourceData)
{
static Unicode::String const delimiters(Unicode::narrowToWide("~"));
static Unicode::String const attributeDelimiters(Unicode::narrowToWide(" "));
Unicode::UnicodeStringVector tokens;
static size_t const resourceAttributeIndex = 5;
if ((Unicode::tokenize(Unicode::narrowToWide(resourceData), tokens, &delimiters, NULL)) && (tokens.size() > resourceAttributeIndex))
{
AddResourceTypeMessageNamespace::ResourceTypeData rtd;
rtd.m_depletedTimestamp = 1;
std::string const sourceGalaxy = Unicode::wideToNarrow(tokens[0]);
int const sourceGalaxyId = ::atoi(Unicode::wideToNarrow(tokens[1]).c_str());
rtd.m_name = Unicode::wideToNarrow(tokens[2]);
NetworkId const resourceType = NetworkId(Unicode::wideToNarrow(tokens[3]));
rtd.m_parentClass = Unicode::wideToNarrow(tokens[4]);
// save off resource attributes
Unicode::UnicodeStringVector attributeTokens;
for (size_t i = resourceAttributeIndex; i < tokens.size(); ++i)
{
attributeTokens.clear();
if ((Unicode::tokenize(tokens[i], attributeTokens, &attributeDelimiters, NULL)) && (attributeTokens.size() == 2))
{
rtd.m_attributes.push_back(std::make_pair(Unicode::wideToNarrow(attributeTokens[0]), ::atoi(Unicode::wideToNarrow(attributeTokens[1]).c_str())));
}
}
if (sourceGalaxy.empty() || (sourceGalaxyId < 1) || (sourceGalaxyId > 255) || rtd.m_name.empty() || !resourceType.isValid() || rtd.m_parentClass.empty() || rtd.m_attributes.empty())
return NetworkId::cms_invalid;
rtd.m_name = std::string("(") + sourceGalaxy + std::string(")") + rtd.m_name;
// resource is locally spawned
if (sourceGalaxy == GameServer::getInstance().getClusterName())
return resourceType;
// get the resource parent class
ServerResourceClassObject * const parentClass = safe_cast<ServerResourceClassObject *>(ServerUniverse::getInstance().getResourceClassByName(rtd.m_parentClass));
if (!parentClass)
return NetworkId::cms_invalid;
// if the resource container is a recycled or permanent resource,
// just "convert" it to use the resource on the local galaxy, since
// recycled or permanent resource are the same on all galaxies
if (parentClass->isRecycled() || parentClass->isPermanent())
{
ResourceTypeObject const * recycledType = parentClass->getAResourceType();
if (recycledType)
return recycledType->getNetworkId();
else
return NetworkId::cms_invalid;
}
rtd.m_networkId = NetworkId(resourceType.getValueWithClusterId(static_cast<uint8>(sourceGalaxyId), static_cast<NetworkId::NetworkIdType>(1), NetworkId::cms_maxNetworkIdWithoutClusterId));
if (rtd.m_networkId.getValue() <= NetworkId::cms_maxNetworkIdWithoutClusterId)
return NetworkId::cms_invalid;
if (!ServerUniverse::getInstance().getImportedResourceTypeById(rtd.m_networkId))
{
ResourceTypeObject * const newType = new ResourceTypeObject(rtd, *parentClass);
ServerUniverse::getInstance().registerResourceTypeObject(*newType, false);
}
return rtd.m_networkId;
}
return NetworkId::cms_invalid;
}
// ----------------------------------------------------------------------
bool ResourceTypeObject::isRecycled() const
{
return m_resourceClass.isRecycled();
}
// ----------------------------------------------------------------------
/**
* We received another AddResourceType message for this type. Check whether
* any of the data needs to be updated.
* Updating the name and depleted timestamp is supported. Other properties
* can't be updated in this manner.
*/
void ResourceTypeObject::handlePossibleUpdates(AddResourceTypeMessageNamespace::ResourceTypeData const & newData)
{
m_depletedTimestamp = newData.m_depletedTimestamp;
if (newData.m_name != m_resourceName)
{
ServerUniverse::getInstance().renameResourceType(m_resourceName,newData.m_name);
m_resourceName=newData.m_name;
}
}
// ----------------------------------------------------------------------
/**
* Roll up random attributes
*/
void ResourceTypeObject::rollAttributes()
{
ServerResourceClassObject const & parent = getParentClass();
ServerResourceClassObject::ResourceAttributeRangesType const & ranges = parent.getResourceAttributeRanges();
bool const recycled = parent.isRecycled();
m_attributes.clear();
for (ServerResourceClassObject::ResourceAttributeRangesType::const_iterator i=ranges.begin(); i!=ranges.end(); ++i)
{
WARNING_DEBUG_FATAL(recycled && (i->second.first != i->second.second),("Data bug: resource type %s is recycled but specifies a range for attribute %s. Recycled resources must always have fixed attributes",getResourceName().c_str(), i->first.c_str()));
IGNORE_RETURN(m_attributes.insert(std::make_pair(i->first, Random::random(i->second.first, i->second.second)))); //lint !e1025 !e1703 // lint can't parse this for some reason
}
}
// ======================================================================
@@ -0,0 +1,107 @@
//========================================================================
//
// ResourceTypeObject.h
//
// copyright 2001 Sony Online Entertainment
//
//========================================================================
#ifndef INCLUDED_ResourceTypeObject_H
#define INCLUDED_ResourceTypeObject_H
#include "serverGame/UniverseObject.h"
#include "serverUtility/ResourceFractalData.h"
#include "sharedObject/CachedNetworkId.h"
class PlanetObject;
class ResourceClassObject;
class ResourcePoolObject;
class ServerResourceClassObject;
// ======================================================================
namespace AddResourceTypeMessageNamespace
{
class ResourceTypeData;
}
// ======================================================================
/**
* A pool of a resource found on a planet.
*
* Represents the planet's supply of a particular resource.
*/
class ResourceTypeObject
{
public:
ResourceTypeObject(ServerResourceClassObject &parent);
ResourceTypeObject(AddResourceTypeMessageNamespace::ResourceTypeData const & data, ServerResourceClassObject & parentClass);
virtual ~ResourceTypeObject();
public:
void setName(const std::string &newName);
void debugOutput(std::string &output, int numSpaces=0) const;
NetworkId const & getNetworkId () const;
std::string const & getResourceName () const;
bool isNamed () const;
bool isDepleted () const;
bool isRecycled () const;
int getNumPools () const;
ServerResourceClassObject const & getParentClass() const;
ResourcePoolObject * getPoolForPlanet(PlanetObject const &planetObject) const;
ResourcePoolObject * getPoolForCurrentPlanet() const;
bool hasPoolForPlanet (const NetworkId &planet) const;
bool isDerivedFrom (const ResourceClassObject &masterClass) const;
void getCrateTemplate (std::string &buffer) const;
void getResourceAttributes (stdvector<std::pair<std::string, Unicode::String> >::fwd &data) const;
const stdmap<std::string, int>::fwd & getResourceAttributes () const;
ResourceFractalData const & getFractalData() const;
uint32 getDepletedTimestamp() const;
void deplete ();
void handlePossibleUpdates(AddResourceTypeMessageNamespace::ResourceTypeData const & newData);
int getAttribute (std::string const & attributeName) const;
void getDataForMessage(AddResourceTypeMessageNamespace::ResourceTypeData & buffer) const;
ResourceTypeObject const * getRecycledVersion () const;
std::string getResourceTypeDataForExport() const;
static NetworkId addImportedResourceType(std::string const & resourceData);
private:
PlanetObject *pickPlanetForSpawn ();
void rollAttributes();
private:
ResourceTypeObject(const ResourceTypeObject& rhs);
ResourceTypeObject& operator=(const ResourceTypeObject& rhs);
private:
NetworkId m_networkId;
std::string m_resourceName;
ServerResourceClassObject & m_resourceClass;
typedef std::map<std::string, int> AttributesType;
AttributesType m_attributes;
ResourceFractalData m_fractalData;
typedef std::map<NetworkId, uint32> FractalSeedsType;
FractalSeedsType m_fractalSeeds;
uint32 m_depletedTimestamp;
mutable std::map<NetworkId, ResourcePoolObject*> m_pools;
};
// ======================================================================
inline bool ResourceTypeObject::isNamed() const
{
return (m_resourceName.size() > 0);
}
inline const std::map<std::string, int> & ResourceTypeObject::getResourceAttributes () const
{
return m_attributes;
}
// ======================================================================
#endif
@@ -0,0 +1,115 @@
//===================================================================
//
// ServerClearCollidableFloraNotification.cpp
// asommers
//
// copyright 2001, sony online entertainment
//
//===================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/ServerClearCollidableFloraNotification.h"
#include "serverGame/ServerObject.h"
#include "sharedGame/SharedObjectTemplate.h"
#include "sharedTerrain/ProceduralTerrainAppearance.h"
#include "sharedTerrain/TerrainObject.h"
//===================================================================
// STATIC PUBLIC ServerClearCollidableFloraNotification
//===================================================================
ServerClearCollidableFloraNotification ServerClearCollidableFloraNotification::ms_instance;
//-------------------------------------------------------------------
ServerClearCollidableFloraNotification& ServerClearCollidableFloraNotification::getInstance ()
{
return ms_instance;
}
//===================================================================
// PUBLIC ServerClearCollidableFloraNotification
//===================================================================
ServerClearCollidableFloraNotification::ServerClearCollidableFloraNotification () :
ObjectNotification ()
{
}
//-------------------------------------------------------------------
ServerClearCollidableFloraNotification::~ServerClearCollidableFloraNotification ()
{
}
//-------------------------------------------------------------------
void ServerClearCollidableFloraNotification::addToWorld (Object& object) const
{
const ServerObject* const serverObject = dynamic_cast<const ServerObject*> (&object);
if (!serverObject)
{
DEBUG_WARNING (true, ("ServerClearCollidableFloraNotification::addToWorld - [%s] is not a server object", object.getObjectTemplate ()->getName ()));
return;
}
const SharedObjectTemplate* const objectTemplate = dynamic_cast<const SharedObjectTemplate*> (serverObject->getSharedTemplate ());
if (!objectTemplate)
{
DEBUG_WARNING (true, ("ServerClearCollidableFloraNotification::addToWorld - [%s] does not have a shared object template", object.getObjectTemplate ()->getName ()));
return;
}
const float clearFloraRadius = objectTemplate->getClearFloraRadius ();
if (clearFloraRadius <= 0.f)
{
DEBUG_WARNING (true, ("ServerClearCollidableFloraNotification::addToWorld - [%s] has a clearFloraRadius (%1.2f) <= 0", object.getObjectTemplate ()->getName (), clearFloraRadius));
return;
}
TerrainObject* const terrainObject = TerrainObject::getInstance ();
if (!terrainObject)
{
DEBUG_WARNING (true, ("ServerClearCollidableFloraNotification::addToWorld - no terrain"));
return;
}
terrainObject->addClearCollidableFloraObject (&object, object.getPosition_w (), clearFloraRadius);
}
//-------------------------------------------------------------------
void ServerClearCollidableFloraNotification::removeFromWorld (Object& object) const
{
TerrainObject* const terrainObject = TerrainObject::getInstance ();
if (!terrainObject)
{
DEBUG_WARNING (true, ("ServerClearCollidableFloraNotification::addToWorld - no terrain"));
return;
}
terrainObject->removeClearCollidableFloraObject (&object);
}
//-------------------------------------------------------------------
bool ServerClearCollidableFloraNotification::positionChanged (Object& object, bool /*dueToParentChange*/, const Vector& /*oldPosition*/) const
{
removeFromWorld (object);
addToWorld (object);
return true;
}
//-------------------------------------------------------------------
bool ServerClearCollidableFloraNotification::positionAndRotationChanged (Object& object, bool /*dueToParentChange*/, const Vector& /*oldPosition*/) const
{
removeFromWorld (object);
addToWorld (object);
return true;
}
//===================================================================
@@ -0,0 +1,48 @@
//===================================================================
//
// ServerClearCollidableFloraNotification.h
// asommers
//
// copyright 2002, sony online entertainment
//
//===================================================================
#ifndef INCLUDED_ServerClearCollidableFloraNotification_H
#define INCLUDED_ServerClearCollidableFloraNotification_H
//===================================================================
#include "sharedObject/ObjectNotification.h"
//===================================================================
class ServerClearCollidableFloraNotification : public ObjectNotification
{
public:
static ServerClearCollidableFloraNotification& getInstance ();
public:
ServerClearCollidableFloraNotification ();
virtual ~ServerClearCollidableFloraNotification ();
virtual void addToWorld (Object& object) const;
virtual void removeFromWorld (Object& object) const;
virtual bool positionChanged (Object& object, bool dueToParentChange, const Vector& oldPosition) const;
virtual bool positionAndRotationChanged (Object& object, bool dueToParentChange, const Vector& oldPosition) const;
private:
ServerClearCollidableFloraNotification (const ServerClearCollidableFloraNotification&);
ServerClearCollidableFloraNotification& operator= (const ServerClearCollidableFloraNotification&);
private:
static ServerClearCollidableFloraNotification ms_instance;
};
//===================================================================
#endif
@@ -0,0 +1,53 @@
// ======================================================================
//
// ServerCollisionProperty.cpp
//
// Copyright 2001 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/ServerCollisionProperty.h"
#include "serverGame/CreatureObject.h"
// ======================================================================
ServerCollisionProperty::ServerCollisionProperty(ServerObject &owner) :
CollisionProperty(owner)
{
}
// ----------------------------------------------------------------------
ServerCollisionProperty::ServerCollisionProperty(ServerObject &owner, SharedObjectTemplate const *objTemplate) :
CollisionProperty(owner, objTemplate)
{
}
// ----------------------------------------------------------------------
bool ServerCollisionProperty::canCollideWith (CollisionProperty const *otherCollision) const
{
if (!otherCollision)
return false;
if (isMobile() && otherCollision->isMobile())
{
ServerObject const * const ownerServerObject = getOwner().asServerObject();
ServerObject const * const otherOwnerServerObject = otherCollision->getOwner().asServerObject();
CreatureObject const * const ownerA = (ownerServerObject != 0) ? ownerServerObject->asCreatureObject() : 0;
CreatureObject const * const ownerB = (otherOwnerServerObject != 0) ? otherOwnerServerObject->asCreatureObject() : 0;
if (ownerA && (ownerA->isDead() || ownerA->isIncapacitated()))
return false;
if (ownerB && (ownerB->isDead() || ownerB->isIncapacitated()))
return false;
}
return CollisionProperty::canCollideWith(otherCollision);
}
// ======================================================================
@@ -0,0 +1,37 @@
// ======================================================================
//
// ServerCollisionProperty.h
// Copyright 2002 Sony Online Entertainment
// All Rights Reserved.
//
// ======================================================================
#ifndef INCLUDED_ServerCollisionProperty_H
#define INCLUDED_ServerCollisionProperty_H
#include "sharedCollision/CollisionProperty.h"
class ServerObject;
class SharedObjectTemplate;
// ----------------------------------------------------------------------
class ServerCollisionProperty : public CollisionProperty
{
public:
ServerCollisionProperty( ServerObject & owner );
ServerCollisionProperty( ServerObject & owner, SharedObjectTemplate const * objTemplate );
virtual bool canCollideWith ( CollisionProperty const * otherCollision ) const;
private:
ServerCollisionProperty();
ServerCollisionProperty( ServerCollisionProperty const & copy );
ServerCollisionProperty & operator = ( ServerCollisionProperty const & copy );
};
// ======================================================================
#endif
@@ -0,0 +1,70 @@
//===================================================================
//
// ServerLotManagerNotification.cpp
// asommers
//
// copyright 2001, sony online entertainment
//
//===================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/ServerLotManagerNotification.h"
#include "serverGame/ServerObject.h"
#include "sharedGame/SharedTangibleObjectTemplate.h"
//===================================================================
// STATIC PUBLIC ServerLotManagerNotification
//===================================================================
ServerLotManagerNotification ServerLotManagerNotification::ms_instance;
//-------------------------------------------------------------------
ServerLotManagerNotification& ServerLotManagerNotification::getInstance ()
{
return ms_instance;
}
//===================================================================
// PUBLIC ServerLotManagerNotification
//===================================================================
ServerLotManagerNotification::ServerLotManagerNotification () :
LotManagerNotification ()
{
}
//-------------------------------------------------------------------
ServerLotManagerNotification::~ServerLotManagerNotification ()
{
}
//-------------------------------------------------------------------
void ServerLotManagerNotification::addToWorld (Object& object) const
{
const ServerObject* const serverObject = dynamic_cast<const ServerObject*> (&object);
if (!serverObject)
{
DEBUG_WARNING (true, ("ServerLotManagerNotification::addToWorld - [%s] is not a server object", object.getObjectTemplate ()->getName ()));
return;
}
const SharedTangibleObjectTemplate* const sharedTangibleObjectTemplate = dynamic_cast<const SharedTangibleObjectTemplate*> (serverObject->getSharedTemplate ());
if (!sharedTangibleObjectTemplate)
{
DEBUG_WARNING (true, ("ServerLotManagerNotification::addToWorld - [%s] does not have a shared tangible object template", object.getObjectTemplate ()->getName ()));
return;
}
const StructureFootprint* const structureFootprint = sharedTangibleObjectTemplate->getStructureFootprint ();
NOT_NULL (structureFootprint);
if (structureFootprint)
LotManagerNotification::addToWorld (object, *structureFootprint);
}
//===================================================================
@@ -0,0 +1,44 @@
//===================================================================
//
// ServerLotManagerNotification.h
// asommers
//
// copyright 2001, sony online entertainment
//
//===================================================================
#ifndef INCLUDED_ServerLotManagerNotification_H
#define INCLUDED_ServerLotManagerNotification_H
//===================================================================
#include "sharedGame/LotManagerNotification.h"
//===================================================================
class ServerLotManagerNotification : public LotManagerNotification
{
public:
static ServerLotManagerNotification& getInstance ();
public:
ServerLotManagerNotification ();
virtual ~ServerLotManagerNotification ();
virtual void addToWorld (Object& object) const;
private:
ServerLotManagerNotification (const ServerLotManagerNotification&);
ServerLotManagerNotification& operator= (const ServerLotManagerNotification&);
private:
static ServerLotManagerNotification ms_instance;
};
//===================================================================
#endif
@@ -0,0 +1,67 @@
//===================================================================
//
// ServerNoBuildNotification.cpp
// asommers
//
// copyright 2001, sony online entertainment
//
//===================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/ServerNoBuildNotification.h"
#include "serverGame/ServerObject.h"
#include "sharedGame/SharedObjectTemplate.h"
//===================================================================
// STATIC PUBLIC ServerNoBuildNotification
//===================================================================
ServerNoBuildNotification ServerNoBuildNotification::ms_instance;
//-------------------------------------------------------------------
ServerNoBuildNotification& ServerNoBuildNotification::getInstance ()
{
return ms_instance;
}
//===================================================================
// PUBLIC ServerNoBuildNotification
//===================================================================
ServerNoBuildNotification::ServerNoBuildNotification () :
NoBuildNotification ()
{
}
//-------------------------------------------------------------------
ServerNoBuildNotification::~ServerNoBuildNotification ()
{
}
//-------------------------------------------------------------------
void ServerNoBuildNotification::addToWorld (Object& object) const
{
const ServerObject* const serverObject = dynamic_cast<const ServerObject*> (&object);
if (!serverObject)
{
DEBUG_WARNING (true, ("ServerNoBuildNotification::addToWorld - [%s] is not a server object", object.getObjectTemplate ()->getName ()));
return;
}
const SharedObjectTemplate* const sharedObjectTemplate = dynamic_cast<const SharedObjectTemplate*> (serverObject->getSharedTemplate ());
if (!sharedObjectTemplate)
{
DEBUG_WARNING (true, ("ServerNoBuildNotification::addToWorld - [%s] does not have a shared object template", object.getObjectTemplate ()->getName ()));
return;
}
const float noBuildRadius = sharedObjectTemplate->getNoBuildRadius ();
NoBuildNotification::addToWorld (object, noBuildRadius);
}
//===================================================================
@@ -0,0 +1,44 @@
//===================================================================
//
// ServerNoBuildNotification.h
// asommers
//
// copyright 2001, sony online entertainment
//
//===================================================================
#ifndef INCLUDED_ServerNoBuildNotification_H
#define INCLUDED_ServerNoBuildNotification_H
//===================================================================
#include "sharedGame/NoBuildNotification.h"
//===================================================================
class ServerNoBuildNotification : public NoBuildNotification
{
public:
static ServerNoBuildNotification& getInstance ();
public:
ServerNoBuildNotification ();
virtual ~ServerNoBuildNotification ();
virtual void addToWorld (Object& object) const;
private:
ServerNoBuildNotification (const ServerNoBuildNotification&);
ServerNoBuildNotification& operator= (const ServerNoBuildNotification&);
private:
static ServerNoBuildNotification ms_instance;
};
//===================================================================
#endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,130 @@
// ======================================================================
//
// ServerObjectBaselinesManager.cpp
//
// Copyright 2000-2003 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/ServerObjectBaselinesManager.h"
#include "serverGame/ContainerInterface.h"
#include "serverGame/ServerObject.h"
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
// ======================================================================
class ContainerOpenInfo
{
public:
ContainerOpenInfo() :
m_client(),
m_sequence(0),
m_containerId(NetworkId::cms_invalid),
m_slotName()
{
}
ContainerOpenInfo(Client &client, int sequence, NetworkId const &containerId, std::string const &slotName) :
m_client(&client),
m_sequence(sequence),
m_containerId(containerId),
m_slotName(slotName)
{
}
void flushContainerOpen() const
{
Client * const client = m_client.getPointer();
if (client)
{
GenericValueTypeMessage<std::pair<int, std::pair<NetworkId, std::string> > > const msg(
"OpenedContainerMessage",
std::make_pair(m_sequence, std::make_pair(m_containerId, m_slotName)));
client->send(msg, true);
}
}
private:
Watcher<Client> m_client;
int m_sequence;
NetworkId m_containerId;
std::string m_slotName;
};
// ======================================================================
static std::set<ServerObject const *> s_topmostObjectsToFlush;
static std::vector<ContainerOpenInfo> s_containerOpens;
// ======================================================================
void ServerObjectBaselinesManager::add(ServerObject const &object)
{
IGNORE_RETURN(s_topmostObjectsToFlush.insert(safe_cast<ServerObject const *>(ContainerInterface::getTopmostContainer(object))));
}
// ----------------------------------------------------------------------
void ServerObjectBaselinesManager::addOpenedContainer(Client &client, int sequence, NetworkId const &containerId, std::string const &slotName)
{
s_containerOpens.push_back(ContainerOpenInfo(client, sequence, containerId, slotName));
}
// ----------------------------------------------------------------------
void ServerObjectBaselinesManager::serverObjDestroyed(ServerObject const &obj)
{
IGNORE_RETURN(s_topmostObjectsToFlush.erase(&obj));
}
// ----------------------------------------------------------------------
void ServerObjectBaselinesManager::onContainerChanged(ServerObject const &object, ServerObject const *oldContainer, ServerObject const *newContainer)
{
// object is changing containers, so we need to adjust which topmost
// parents may potentially have pending baselines.
ServerObject const * const oldTopmost = oldContainer ? safe_cast<ServerObject const *>(ContainerInterface::getTopmostContainer(*oldContainer)) : &object;
ServerObject const * const newTopmost = newContainer ? safe_cast<ServerObject const *>(ContainerInterface::getTopmostContainer(*newContainer)) : &object;
// if object keeps the same topmost parent, there are no updates to make
if (oldTopmost == newTopmost)
return;
std::set<ServerObject const *>::iterator i = s_topmostObjectsToFlush.find(oldTopmost);
if (i == s_topmostObjectsToFlush.end())
return; // old topmost had no baselines pending, so nothing to update
// if object was previously a top level object, remove from the set
if (!oldContainer)
s_topmostObjectsToFlush.erase(i);
// There were baselines pending for the old topmost or its children,
// which means possible for object or its contents, so we add the new
// topmost to the set of pending baselines.
IGNORE_RETURN(s_topmostObjectsToFlush.insert(newTopmost));
}
// ----------------------------------------------------------------------
void ServerObjectBaselinesManager::update()
{
// flush baselines
{
for (std::set<ServerObject const *>::const_iterator i = s_topmostObjectsToFlush.begin(); i != s_topmostObjectsToFlush.end(); ++i)
(*i)->flushCreateMessages();
s_topmostObjectsToFlush.clear();
}
// flush container opens
{
for (std::vector<ContainerOpenInfo>::const_iterator i = s_containerOpens.begin(); i != s_containerOpens.end(); ++i)
(*i).flushContainerOpen();
s_containerOpens.clear();
}
}
// ======================================================================
@@ -0,0 +1,39 @@
// ======================================================================
//
// ServerObjectBaselinesManager.h
//
// Copyright 2000-2003 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_ServerObjectBaselinesManager_H
#define INCLUDED_ServerObjectBaselinesManager_H
// ======================================================================
class Client;
class NetworkId;
class ServerObject;
// ======================================================================
class ServerObjectBaselinesManager
{
public:
static void add(ServerObject const &object);
static void addOpenedContainer(Client &client, int sequence, NetworkId const &containerId, std::string const &slotName);
static void update();
static void serverObjDestroyed(ServerObject const &obj);
static void onContainerChanged(ServerObject const &object, ServerObject const *oldContainer, ServerObject const *newContainer);
private:
ServerObjectBaselinesManager();
~ServerObjectBaselinesManager();
ServerObjectBaselinesManager(ServerObjectBaselinesManager const &);
ServerObjectBaselinesManager &operator=(ServerObjectBaselinesManager const &);
};
// ======================================================================
#endif // INCLUDED_ServerObjectBaselinesManager_H
@@ -0,0 +1,198 @@
//===================================================================
//
// ServerObjectTerrainModificationNotification.cpp
// asommers
//
// copyright 2001, sony online entertainment
//
//===================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/ServerObjectTerrainModificationNotification.h"
#include "serverGame/ServerObject.h"
#include "serverGame/ServerWorld.h"
#include "sharedGame/SharedObjectTemplate.h"
#include "sharedMath/Vector2d.h"
#include "sharedTerrain/ProceduralTerrainAppearance.h"
#include "sharedTerrain/TerrainModificationHelper.h"
//===================================================================
namespace ServerObjectTerrainModificationNotificationNamespace
{
void snapObjectsToTerrain (Rectangle2d const & extent, float const height)
{
Vector const center (extent.getCenter ().x, height, extent.getCenter ().y);
float const radius = sqrt (sqr (extent.getWidth ()) + sqr (extent.getHeight ()));
typedef std::vector<ServerObject *> ServerObjectList;
ServerObjectList result;
ServerWorld::findObjectsInRange (center, radius, result);
ServerObjectList::iterator end = result.end ();
for (ServerObjectList::iterator iter = result.begin (); iter != end; ++iter)
{
ServerObject * const serverObject = *iter;
if (serverObject)
{
SharedObjectTemplate const * const sharedObjectTemplate = serverObject->getSharedTemplate ();
if (sharedObjectTemplate)
{
SharedObjectTemplate::GameObjectType const gameObjectType = sharedObjectTemplate->getGameObjectType ();
if (gameObjectType == SharedObjectTemplate::GOT_corpse)
World::snapObjectToTerrain (serverObject);
}
}
}
}
}
using namespace ServerObjectTerrainModificationNotificationNamespace;
//===================================================================
ProceduralTerrainAppearance* ServerObjectTerrainModificationNotification::ms_terrainAppearance;
ServerObjectTerrainModificationNotification ServerObjectTerrainModificationNotification::ms_instance;
//===================================================================
ServerObjectTerrainModificationNotification &ServerObjectTerrainModificationNotification::getInstance()
{
return ms_instance;
}
//-------------------------------------------------------------------
void ServerObjectTerrainModificationNotification::setTerrainAppearance (ProceduralTerrainAppearance* const terrainAppearance)
{
ms_terrainAppearance = terrainAppearance;
}
//-------------------------------------------------------------------
ServerObjectTerrainModificationNotification::ServerObjectTerrainModificationNotification () :
ObjectNotification ()
{
}
//-------------------------------------------------------------------
ServerObjectTerrainModificationNotification::~ServerObjectTerrainModificationNotification ()
{
}
//-------------------------------------------------------------------
void ServerObjectTerrainModificationNotification::addToWorld (Object& object) const
{
//-- insert the layer into the terrain system
ServerObject* const serverObject = object.asServerObject();
TerrainGenerator::Layer* const layer = serverObject->getLayer ();
ms_terrainAppearance->addLayer (layer);
updateTerrain (object, false, true);
}
//-------------------------------------------------------------------
void ServerObjectTerrainModificationNotification::removeFromWorld (Object& object) const
{
//-- remove the layer from the terrain system
ServerObject* const serverObject = object.asServerObject();
TerrainGenerator::Layer* const layer = serverObject->getLayer ();
ms_terrainAppearance->removeLayer (layer);
updateTerrain (object, true, false);
}
//-------------------------------------------------------------------
bool ServerObjectTerrainModificationNotification::positionChanged (Object& object, bool /*dueToParentChange*/, const Vector& /*oldPosition*/) const
{
//-- update the layer with new position data
if (object.isInWorld ())
updateTerrain (object, true, true);
return true;
}
//-------------------------------------------------------------------
void ServerObjectTerrainModificationNotification::rotationChanged (Object& object, bool /*dueToParentChange*/) const
{
//-- update the layer with new position data
if (object.isInWorld ())
updateTerrain (object, false, false);
}
//-------------------------------------------------------------------
bool ServerObjectTerrainModificationNotification::positionAndRotationChanged (Object& object, bool /*dueToParentChange*/, const Vector& /*oldPosition*/) const
{
//-- update the layer with new position data
if (object.isInWorld ())
updateTerrain (object, true, true);
return true;
}
//-------------------------------------------------------------------
void ServerObjectTerrainModificationNotification::updateTerrain (Object& object, bool const updateOldExtent, bool const updateNewExtent) const
{
ServerObject* const serverObject = object.asServerObject();
TerrainGenerator::Layer* const layer = serverObject->getLayer ();
ProceduralTerrainAppearance* const proceduralTerrainAppearance = safe_cast<ProceduralTerrainAppearance*> (ms_terrainAppearance);
NOT_NULL (proceduralTerrainAppearance);
//-- get the new position of the object
const Vector position = object.getPosition_w ();
//-- save the current extent of the layer
layer->calculateExtent ();
Rectangle2d oldExtent;
float oldHeight = 0.f;
bool hasOldExtent = updateOldExtent && layer->getUseExtent ();
if (hasOldExtent)
{
oldExtent = layer->getExtent ();
oldHeight = layer->getModificationHeight ();
}
//-- calculate the updated layer information (position and heights)
const Vector2d& position2d = Vector2d (position.x, position.z);
TerrainModificationHelper::setPosition (layer, position2d);
TerrainModificationHelper::setRotation (layer, object.getObjectFrameK_w ().theta ());
TerrainModificationHelper::setHeight (layer, ms_terrainAppearance->generateHeight_expensive (position2d));
//-- prepare the terrain
ms_terrainAppearance->prepareGenerator ();
//-- get the new extent of the layer
layer->calculateExtent ();
Rectangle2d newExtent;
float newHeight = 0.f;
bool hasNewExtent = updateNewExtent && layer->getUseExtent ();
if (hasNewExtent)
{
newExtent = layer->getExtent ();
newHeight = layer->getModificationHeight ();
}
//-- tell the terrain system the old and new extent regions have changed
if (hasOldExtent)
{
ms_terrainAppearance->invalidateRegion (oldExtent);
snapObjectsToTerrain (oldExtent, oldHeight);
}
if (hasNewExtent)
{
ms_terrainAppearance->invalidateRegion (newExtent);
snapObjectsToTerrain (newExtent, newHeight);
}
}
//===================================================================
@@ -0,0 +1,57 @@
//===================================================================
//
// ServerObjectTerrainModificationNotification.h
// asommers
//
// copyright 2001, sony online entertainment
//
//===================================================================
#ifndef INCLUDED_ServerObjectTerrainModificationNotification_H
#define INCLUDED_ServerObjectTerrainModificationNotification_H
//===================================================================
class ProceduralTerrainAppearance;
#include "sharedObject/ObjectNotification.h"
//===================================================================
class ServerObjectTerrainModificationNotification : public ObjectNotification
{
public:
static void setTerrainAppearance (ProceduralTerrainAppearance* const terrainAppearance);
static ServerObjectTerrainModificationNotification &getInstance();
public:
ServerObjectTerrainModificationNotification ();
virtual ~ServerObjectTerrainModificationNotification ();
virtual void addToWorld (Object& object) const;
virtual void removeFromWorld (Object& object) const;
virtual bool positionChanged (Object& object, bool dueToParentChange, const Vector& oldPosition) const;
virtual void rotationChanged (Object& object, bool dueToParentChange) const;
virtual bool positionAndRotationChanged (Object& object, bool dueToParentChange, const Vector& oldPosition) const;
private:
void updateTerrain (Object& object, bool updateOldExtent, bool updateNewExtent) const;
private:
ServerObjectTerrainModificationNotification (const ServerObjectTerrainModificationNotification&);
ServerObjectTerrainModificationNotification& operator= (const ServerObjectTerrainModificationNotification&);
private:
static ProceduralTerrainAppearance* ms_terrainAppearance;
static ServerObjectTerrainModificationNotification ms_instance;
};
//===================================================================
#endif
@@ -0,0 +1,455 @@
// ======================================================================
//
// ServerObject_AuthTransfer.cpp
//
// Copyright 2004 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/ServerObject.h"
#include "serverGame/AuthTransferTracker.h"
#include "serverGame/ConfigServerGame.h"
#include "serverGame/ConnectionServerConnection.h"
#include "serverGame/ContainerInterface.h"
#include "serverGame/CreatureObject.h"
#include "serverGame/GameServer.h"
#include "serverGame/ObserveTracker.h"
#include "serverGame/PlayerObject.h"
#include "serverGame/PositionUpdateTracker.h"
#include "serverGame/ServerController.h"
#include "serverGame/ServerMessageForwarding.h"
#include "serverGame/ServerUIManager.h"
#include "serverGame/ServerWorld.h"
#include "serverScript/GameScriptObject.h"
#include "serverNetworkMessages/AuthTransferClientMessage.h"
#include "serverNetworkMessages/GameConnectionServerMessages.h"
#include "serverNetworkMessages/GameServerForceChangeAuthorityMessage.h"
#include "serverNetworkMessages/PlanetRemoveObject.h"
#include "serverNetworkMessages/PlayedTimeAccumMessage.h"
#include "serverNetworkMessages/SetAuthoritativeMessage.h"
#include "serverNetworkMessages/UnloadObjectMessage.h"
#include "sharedMathArchive/TransformArchive.h"
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
#include "sharedNetworkMessages/MessageQueueGenericValueType.h"
#include "sharedObject/NetworkIdManager.h"
// ======================================================================
namespace ServerObject_AuthTransferNamespace
{
// ----------------------------------------------------------------------
void getContainedClients(ServerObject &obj, std::vector<Watcher<Client> > &containedClients)
{
// find all clients for primary controlled objects in the containment hierarchy under obj (including obj)
Client * const client = obj.getClient();
if (client && client->getCharacterObjectId() == obj.getNetworkId())
containedClients.push_back(Watcher<Client>(client));
Container * const container = ContainerInterface::getContainer(obj);
if (container)
{
for (ContainerIterator i = container->begin(); i != container->end(); ++i)
{
ServerObject * const containedObject = safe_cast<ServerObject *>((*i).getObject());
if (containedObject)
getContainedClients(*containedObject, containedClients);
}
}
}
// ----------------------------------------------------------------------
}
using namespace ServerObject_AuthTransferNamespace;
// ======================================================================
void ServerObject::beginAuthTransfer(uint32 pid) const
{
AuthTransferTracker::beginAuthTransfer(getNetworkId(), pid, getExposedProxyList());
Container const * const container = ContainerInterface::getContainer(*this);
if (container)
{
for (ContainerConstIterator containerIterator = container->begin(); containerIterator != container->end(); ++containerIterator)
{
ServerObject const * const containedObject = safe_cast<ServerObject const *>((*containerIterator).getObject());
if (containedObject)
containedObject->beginAuthTransfer(pid);
}
}
}
// ----------------------------------------------------------------------
void ServerObject::transferAuthoritySceneChange(uint32 pid)
{
std::vector<Watcher<Client> > containedClients;
getContainedClients(*this, containedClients);
{
for (std::vector<Watcher<Client> >::const_iterator i = containedClients.begin(); i != containedClients.end(); ++i)
{
Client * const client = (*i).getPointer();
if (client)
{
ServerObject * const characterObject = (*i)->getCharacterObject();
if (characterObject)
characterObject->onClientAboutToLoad();
}
}
}
beginAuthTransfer(pid);
ProxyList proxyList = getExposedProxyList();
// Before we send baselines to the new server, we need to clear out the proxy list,
if (!m_proxyServerProcessIds.empty())
m_proxyServerProcessIds.clear();
setAuthServerProcessId(pid);
sendDeltasForSelfAndContents(&proxyList);
// get rid of the old proxies now, because we already had to remove them from the proxy list
if (!proxyList.empty())
{
ServerMessageForwarding::begin(std::vector<uint32>(proxyList.begin(), proxyList.end()));
UnloadObjectMessage const unloadMessage(getNetworkId());
ServerMessageForwarding::send(unloadMessage);
ServerMessageForwarding::end();
}
// set up message forwarding
ServerMessageForwarding::begin(pid);
forwardServerCreateAndBaselines();
// build transfer authority message
SetAuthoritativeMessage const sam(getNetworkId(), pid, true, false, NetworkId::cms_invalid, getTransform_o2w(), true);
releaseAuthority(pid);
{
for (std::vector<Watcher<Client> >::const_iterator i = containedClients.begin(); i != containedClients.end(); ++i)
{
Client * const client = (*i).getPointer();
if (client)
{
ObserveTracker::onClientAboutToTransferAuthority(*client);
// transfer the client to the new authoritative server before
// transfering authority so that when the new authoritative
// takes authority, it will immediately attach the client
// to the object, so there's no possibility of the game
// client missing updates to the object
ConnectionServerConnection * const connectionServer = client->getConnection();
if (connectionServer)
{
DEBUG_REPORT_LOG(ConfigServerGame::getLogObservers(), ("%s is now sending AuthTransferClientMessage\n", client->getCharacterObjectId().getValueString().c_str()));
AuthTransferClientMessage const atcm(
client->getCharacterObjectId(),
connectionServer->getRemoteAddress(),
connectionServer->getRemotePort(),
false,
client->getAccountName(),
client->getIpAddress(),
client->isSecure(),
client->getStationId(),
NULL,
client->getGameFeatures(),
client->getSubscriptionFeatures(),
client->getAccountFeatureIds(),
client->getEntitlementTotalTime(),
client->getEntitlementEntitledTime(),
client->getEntitlementTotalTimeSinceLastLogin(),
client->getEntitlementEntitledTimeSinceLastLogin(),
client->getBuddyPoints(),
GameServer::getInstance().getProcessId(),
client->getConsumedRewardEvents(),
client->getClaimedRewardItems(),
client->isUsingAdminLogin(),
static_cast<int>(client->getCombatSpamFilter()),
client->getCombatSpamRangeSquaredFilter(),
client->getFurnitureRotationDegree(),
client->getHasUnoccupiedJediSlot(),
client->getIsJediSlotCharacter());
ServerMessageForwarding::send(atcm);
}
client->clearControlledObjects();
}
}
}
// transfer authority to the new authoritative server
ServerMessageForwarding::send(sam);
// End forwarding
ServerMessageForwarding::end();
}
// ----------------------------------------------------------------------
void ServerObject::transferAuthorityNoSceneChange(uint32 pid, bool skipLoadScreen, const NetworkId &goalCell, const Transform &goalTransform, bool informPlanetServer)
{
beginAuthTransfer(pid);
ProxyList proxyList = getExposedProxyList();
m_proxyServerProcessIds.insert(GameServer::getInstance().getProcessId());
bool needCreate = !isProxiedOnServer(pid);
setAuthServerProcessId(pid);
sendDeltasForSelfAndContents(&proxyList);
// Set up message forwarding
ServerMessageForwarding::begin(pid);
if (needCreate)
forwardServerCreateAndBaselines();
// build transfer authority message
SetAuthoritativeMessage const sam(getNetworkId(), pid, false, false, goalCell, goalTransform, true);
std::vector<Watcher<Client> > containedClients;
getContainedClients(*this, containedClients);
releaseAuthority(pid);
for (std::vector<Watcher<Client> >::const_iterator i = containedClients.begin(); i != containedClients.end(); ++i)
{
Client * const client = (*i).getPointer();
if (client)
{
// force any UpdatePvpStatusMessage waiting to be sent to this
// client at the end of the frame to be send now, because the
// client object is going away, and the receiving game server
// doesn't have the list of UpdatePvpStatusMessage waiting to
// be sent to this client at the end of the frame; we only need
// to do this when there is an authority transfer that doesn't
// involve a scene change, because with scene change, the game
// client will unload all objects and get fresh baselines and
// UpdatePvpStatusMessage for observed objects
PvpUpdateObserver::sendUpdateAndRemoveClientFromPvpStatusCache(client);
ObserveTracker::onClientAboutToTransferAuthority(*client);
// transfer the client to the new authoritative server before
// transfering authority so that when the new authoritative
// takes authority, it will immediately attach the client
// to the object, so there's no possibility of the game
// client missing updates to the object
ConnectionServerConnection * const connectionServer = client->getConnection();
if (connectionServer)
{
std::vector<NetworkId> observeListIds;
if (skipLoadScreen)
{
Client::ObservingList const &observeList = client->getObserving();
for (Client::ObservingList::const_iterator j = observeList.begin(); j != observeList.end(); ++j)
observeListIds.push_back((*j)->getNetworkId());
}
DEBUG_REPORT_LOG(ConfigServerGame::getLogObservers(), ("%s is now sending AuthTransferClientMessage\n", client->getCharacterObjectId().getValueString().c_str()));
AuthTransferClientMessage const atcm(
client->getCharacterObjectId(),
connectionServer->getRemoteAddress(),
connectionServer->getRemotePort(),
skipLoadScreen,
client->getAccountName(),
client->getIpAddress(),
client->isSecure(),
client->getStationId(),
(observeListIds.empty() ? NULL : &observeListIds),
client->getGameFeatures(),
client->getSubscriptionFeatures(),
client->getAccountFeatureIds(),
client->getEntitlementTotalTime(),
client->getEntitlementEntitledTime(),
client->getEntitlementTotalTimeSinceLastLogin(),
client->getEntitlementEntitledTimeSinceLastLogin(),
client->getBuddyPoints(),
GameServer::getInstance().getProcessId(),
client->getConsumedRewardEvents(),
client->getClaimedRewardItems(),
client->isUsingAdminLogin(),
static_cast<int>(client->getCombatSpamFilter()),
client->getCombatSpamRangeSquaredFilter(),
client->getFurnitureRotationDegree(),
client->getHasUnoccupiedJediSlot(),
client->getIsJediSlotCharacter());
ServerMessageForwarding::send(atcm);
}
client->clearControlledObjects();
}
}
// transfer authority to the new authoritative server
ServerMessageForwarding::send(sam);
if (informPlanetServer)
{
GameServerForceChangeAuthorityMessage const authMessage(getNetworkId(), GameServer::getInstance().getProcessId(), pid);
GameServer::getInstance().sendToPlanetServer(authMessage);
}
// End forwarding
ServerMessageForwarding::end();
}
// ----------------------------------------------------------------------
void ServerObject::transferAuthority(uint32 pid, bool skipLoadScreen, bool handlingCrash, bool informPlanetServer)
{
transferAuthority(pid, skipLoadScreen, handlingCrash, getAttachedTo() ? getAttachedTo()->getNetworkId() : NetworkId::cms_invalid, getTransform_o2p(), informPlanetServer);
}
// ----------------------------------------------------------------------
void ServerObject::transferAuthority(uint32 pid, bool skipLoadScreen, bool handlingCrash, const NetworkId &goalCell, const Transform &goalTransform, bool informPlanetServer)
{
// If we are handling a crash and being told to become authoritative, we do so directly.
// If we are not authoritative, but have been set as the auth server process id for this object,
// then we are completing the transfer process and should set ourselves authoritative.
// If neither of these is true, then we are beginning the auth transfer process, or should tell
// the auth object to do so if we aren't it.
if ( pid == GameServer::getInstance().getProcessId()
&& (handlingCrash || getAuthServerProcessId() == GameServer::getInstance().getProcessId()))
{
// setting authority to this server
if (!isAuthoritative())
{
if (handlingCrash)
{
// normally this stuff is done by the server that's giving up authority
setAuthServerProcessId(pid);
if (isPlayerControlled())
{
std::vector<NetworkId> nothing; //TODO: do we need to worry about this in the crash recovery case?
TransferControlMessage const tcm(getNetworkId(), pid, true, nothing);
GameServer::getInstance().sendToConnectionServers(tcm);
}
}
if (goalCell == NetworkId::cms_invalid)
{
safe_cast<ServerController *>(getController())->teleport(goalTransform, 0);
setAuthority();
}
else
{
ServerObject * const cell = safe_cast<ServerObject *>(NetworkIdManager::getObjectById(goalCell));
safe_cast<ServerController *>(getController())->teleport(goalTransform, cell);
setAuthority();
}
}
}
else
{
// setting authority to a different server
if (!isAuthoritative())
{
sendControllerMessageToAuthServer(CM_transferAuthority, new MessageQueueGenericValueType<std::pair<uint32, bool> >(std::make_pair(pid, skipLoadScreen)));
return;
}
if (GameServer::getInstance().isGameServerConnected(pid))
{
if (getSceneId() != ServerWorld::getSceneId() && getSceneId() != "universe")
transferAuthoritySceneChange(pid);
else
transferAuthorityNoSceneChange(pid, skipLoadScreen, goalCell, goalTransform, informPlanetServer);
}
else
{
WARNING(true, ("GameServer(%d) is not connected to this gameserver! TransferAuthority for (%s : %s) will not continue because it CANNOT send authority transfer network messages to a server that is not running or not connected!", pid, getObjectTemplateName(), getNetworkId().getValueString().c_str()));
}
}
}
// ----------------------------------------------------------------------
void ServerObject::releaseAuthority(uint32 newProcessId)
{
DEBUG_REPORT_LOG(ConfigServerGame::getLogObservers(), ("Called releaseAuthority on %s to process %lu\n", getNetworkId().getValueString().c_str(), newProcessId));
PositionUpdateTracker::flushPositionUpdate(*this);
// remove our synchronizedUi
ServerSynchronizedUi * const syncUI = m_synchronizedUi.getPointer();
if (syncUI)
{
DEBUG_WARNING(true, ("Object %s is being set non-authoritative but still has a synchronizedUi", getNetworkId().getValueString().c_str()));
syncUI->onAuthorityTransferred();
delete syncUI;
}
NetworkController * const controller = safe_cast<NetworkController *>(getController());
NOT_NULL(controller);
if (isPlayerControlled())
{
//DEBUG_WARNING(true, ("ServerUIManager: ServerObject is calling clientLosingAuthority, network id = %s, newProcessId = %lu", getNetworkId().getValueString().c_str(), newProcessId));
ServerUIManager::onPlayerAuthorityTransferred(getNetworkId());
}
PlayerObject *thisAsPlayer = this->asPlayerObject();
if(thisAsPlayer)
{
PlayedTimeAccumMessage ptam(getNetworkId(), thisAsPlayer->getPlayedTimeAccumOnly());
ServerMessageForwarding::send(ptam);
}
else
{
CreatureObject *thisAsCreature = this->asCreatureObject();
if(thisAsCreature)
{
PlayedTimeAccumMessage ptam(getNetworkId(), thisAsCreature->getPseudoPlayedTime());
ServerMessageForwarding::send(ptam);
}
}
Container * const container = ContainerInterface::getContainer(*this);
if (container)
{
std::vector<CachedNetworkId> idList;
idList.reserve(static_cast<size_t>(container->getNumberOfItems()));
for (ContainerIterator containerIterator = container->begin(); containerIterator != container->end(); ++containerIterator)
idList.push_back(*containerIterator);
for (std::vector<CachedNetworkId>::const_iterator i = idList.begin(); i != idList.end(); ++i)
{
ServerObject * const containedObject = safe_cast<ServerObject*>(i->getObject());
if (containedObject)
containedObject->releaseAuthority(newProcessId);
}
}
// if we're in another scene and losing authority, unload and notify the planet server
if ( getSceneId() != ServerWorld::getSceneId()
&& getSceneId() != "universe"
&& (isPlayerControlled() || ContainerInterface::getTopmostContainer(*this) == this))
{
PlanetRemoveObject const removeMessage(getNetworkId());
GameServer::getInstance().sendToPlanetServer(removeMessage);
unload();
}
controller->setAuthoritative(false);
if (getScriptObject())
getScriptObject()->setOwnerIsAuthoritative(false, newProcessId);
virtualOnReleaseAuthority();
}
// ======================================================================
@@ -0,0 +1,415 @@
// ======================================================================
//
// ServerObject_ObjVar.cpp
//
// Copyright 2004 Sony Online Entertainment
//
// ======================================================================
#include "serverGame/FirstServerGame.h"
#include "serverGame/ServerObject.h"
#include "UnicodeUtils.h"
#include "sharedFoundation/DynamicVariableLocationData.h"
#include "sharedNetworkMessages/MessageQueueGenericValueType.h"
// ======================================================================
void ServerObject::removeObjVarItem(std::string const &name)
{
if (isAuthoritative())
{
IGNORE_RETURN(m_objVars.removeItemByName(name));
}
else
{
sendControllerMessageToAuthServer(
CM_removeObjVarItem,
new MessageQueueGenericValueType<std::string>(name));
}
}
// ----------------------------------------------------------------------
void ServerObject::eraseObjVarListEntries(std::string const &name)
{
if (isAuthoritative())
{
IGNORE_RETURN(m_objVars.removeItemByName(name));
}
else
{
sendControllerMessageToAuthServer(
CM_eraseObjVarListEntries,
new MessageQueueGenericValueType<std::string>(name));
}
}
// ----------------------------------------------------------------------
void ServerObject::copyObjVars(std::string const &name, ServerObject const &srcObject, std::string const &srcVarName)
{
m_objVars.copy(name, srcObject.getObjVars(), srcVarName);
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, int value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
sendControllerMessageToAuthServer(
CM_setIntDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, int> >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, std::vector<int> const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
if (DynamicVariable::getUTF8Length(value) > DynamicVariable::MAX_DYNAMIC_VARIABLE_UTF8_LENGTH)
return false;
sendControllerMessageToAuthServer(
CM_setIntArrayDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, std::vector<int> > >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, float value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
sendControllerMessageToAuthServer(
CM_setFloatDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, float> >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, std::vector<float> const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
if (DynamicVariable::getUTF8Length(value) > DynamicVariable::MAX_DYNAMIC_VARIABLE_UTF8_LENGTH)
return false;
sendControllerMessageToAuthServer(
CM_setFloatArrayDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, std::vector<float> > >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, std::string const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
if (DynamicVariable::getUTF8Length(value) > DynamicVariable::MAX_DYNAMIC_VARIABLE_UTF8_LENGTH)
return false;
sendControllerMessageToAuthServer(
CM_setStringDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, Unicode::String> >(
std::make_pair(name, Unicode::narrowToWide(value))));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, Unicode::String const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
if (DynamicVariable::getUTF8Length(value) > DynamicVariable::MAX_DYNAMIC_VARIABLE_UTF8_LENGTH)
return false;
sendControllerMessageToAuthServer(
CM_setStringDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, Unicode::String> >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, std::vector<Unicode::String> const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
if (DynamicVariable::getUTF8Length(value) > DynamicVariable::MAX_DYNAMIC_VARIABLE_UTF8_LENGTH)
return false;
sendControllerMessageToAuthServer(
CM_setStringArrayDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, std::vector<Unicode::String> > >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, NetworkId const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
sendControllerMessageToAuthServer(
CM_setObjIdDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, NetworkId> >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, std::vector<NetworkId> const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
if (DynamicVariable::getUTF8Length(value) > DynamicVariable::MAX_DYNAMIC_VARIABLE_UTF8_LENGTH)
return false;
sendControllerMessageToAuthServer(
CM_setObjIdArrayDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, std::vector<NetworkId> > >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, DynamicVariableLocationData const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
sendControllerMessageToAuthServer(
CM_setLocationDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, DynamicVariableLocationData> >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, std::vector<DynamicVariableLocationData> const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
if (DynamicVariable::getUTF8Length(value) > DynamicVariable::MAX_DYNAMIC_VARIABLE_UTF8_LENGTH)
return false;
sendControllerMessageToAuthServer(
CM_setLocationArrayDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, std::vector<DynamicVariableLocationData> > >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, StringId const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
if (DynamicVariable::getUTF8Length(value) > DynamicVariable::MAX_DYNAMIC_VARIABLE_UTF8_LENGTH)
return false;
sendControllerMessageToAuthServer(
CM_setStringIdDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, StringId> >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, std::vector<StringId> const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
if (DynamicVariable::getUTF8Length(value) > DynamicVariable::MAX_DYNAMIC_VARIABLE_UTF8_LENGTH)
return false;
sendControllerMessageToAuthServer(
CM_setStringIdArrayDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, std::vector<StringId> > >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, Transform const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
if (DynamicVariable::getUTF8Length(value) > DynamicVariable::MAX_DYNAMIC_VARIABLE_UTF8_LENGTH)
return false;
sendControllerMessageToAuthServer(
CM_setTransformDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, Transform> >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, std::vector<Transform> const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
if (DynamicVariable::getUTF8Length(value) > DynamicVariable::MAX_DYNAMIC_VARIABLE_UTF8_LENGTH)
return false;
sendControllerMessageToAuthServer(
CM_setTransformArrayDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, std::vector<Transform> > >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, Vector const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
if (DynamicVariable::getUTF8Length(value) > DynamicVariable::MAX_DYNAMIC_VARIABLE_UTF8_LENGTH)
return false;
sendControllerMessageToAuthServer(
CM_setVectorDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, Vector> >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, std::vector<Vector> const &value)
{
if (isAuthoritative())
{
if (!m_objVars.setItem(name, value))
return false;
}
else
{
if (DynamicVariable::getUTF8Length(value) > DynamicVariable::MAX_DYNAMIC_VARIABLE_UTF8_LENGTH)
return false;
sendControllerMessageToAuthServer(
CM_setVectorArrayDynamicVariable,
new MessageQueueGenericValueType<std::pair<std::string, std::vector<Vector> > >(
std::make_pair(name, value)));
}
return true;
}
// ----------------------------------------------------------------------
bool ServerObject::setObjVarItem(std::string const &name, DynamicVariable const &value)
{
FATAL(!isAuthoritative(), ("setObjVarItem using a DynamicVariable value can only be used on auth objects"));
if (!m_objVars.setItem(name, value))
return false;
return true;
}
// ======================================================================

Some files were not shown because too many files have changed in this diff Show More