You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
242 lines
9.4 KiB
242 lines
9.4 KiB
/*==LICENSE==* |
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools |
|
Copyright (C) 2011 Cyan Worlds, Inc. |
|
|
|
This program is free software: you can redistribute it and/or modify |
|
it under the terms of the GNU General Public License as published by |
|
the Free Software Foundation, either version 3 of the License, or |
|
(at your option) any later version. |
|
|
|
This program is distributed in the hope that it will be useful, |
|
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
GNU General Public License for more details. |
|
|
|
You should have received a copy of the GNU General Public License |
|
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
Additional permissions under GNU GPL version 3 section 7 |
|
|
|
If you modify this Program, or any covered work, by linking or |
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
(or a modified version of those libraries), |
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
licensors of this Program grant you additional |
|
permission to convey the resulting work. Corresponding Source for a |
|
non-source form of such a combination shall include the source code for |
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
work. |
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com |
|
or by snail mail at: |
|
Cyan Worlds, Inc. |
|
14617 N Newport Hwy |
|
Mead, WA 99021 |
|
|
|
*==LICENSE==*/ |
|
/** \file plAvatarMgr.h |
|
Gathering place for global animations and miscellaneous avatar data. |
|
Ideally this stuff will all be migrated into the resource manager. */ |
|
#ifndef PLAVATARMGR_INC |
|
#define PLAVATARMGR_INC |
|
|
|
#include "hsStlUtils.h" |
|
#include "hsStlSortUtils.h" |
|
#include "hsGeometry3.h" |
|
|
|
#include "pnKeyedObject/hsKeyedObject.h" |
|
#include "plMessage/plLoadAvatarMsg.h" |
|
|
|
// This is still pretty much a hack, but it's a compartmentalized hack instead of the previous |
|
// interwoven spaghetti hack. |
|
|
|
class plSeekPointMod; |
|
class plOneShotMod; |
|
class plAGMasterMod; |
|
class plArmatureMod; |
|
class plSpawnModifier; |
|
class plKey; |
|
class plLoadAvatarMsg; |
|
class plMaintainersMarkerModifier; |
|
class plDniCoordinateInfo; |
|
class plAvCoopMsg; |
|
class plNotifyMsg; |
|
class plCoopCoordinator; |
|
class plLoadCloneMsg; |
|
class plStatusLog; |
|
|
|
/** \class plAvatarMgr |
|
Gathering place for global animations and miscellaneous avatar data. |
|
Ideally this stuff will all be migrated into the resource manager. |
|
This class is 100% static and must be explictly cleared when |
|
resetting the scene on shutdown or when rebuilding the scene for export. |
|
*/ |
|
class plAvatarMgr : public hsKeyedObject |
|
{ |
|
public: |
|
typedef std::vector<plArmatureMod*> plArmatureModPtrVec; |
|
|
|
enum AvatarTypeMask |
|
{ |
|
Human = 1, |
|
Player = 2 |
|
}; |
|
|
|
plAvatarMgr(); // can only be constructed by itself (singleton) |
|
virtual ~plAvatarMgr(); |
|
|
|
CLASSNAME_REGISTER( plAvatarMgr ); |
|
GETINTERFACE_ANY( plAvatarMgr, hsKeyedObject ); |
|
|
|
// \{ |
|
/** Seek points are alignment points used for aligning |
|
the avatar before playing a detail interaction animation. |
|
These are registered by name here primarily for debugging |
|
and ad-hoc scripting. In final releases, we'll be able to |
|
do away with this bookeeping entirely. */ |
|
void AddSeekPoint(plSeekPointMod *seekpoint); |
|
void RemoveSeekPoint(plSeekPointMod *seekpoint); |
|
plSeekPointMod *FindSeekPoint(const plString &name); |
|
// \} |
|
|
|
// \{ |
|
/** One shots are registered here for debugging and ad-hoc |
|
scripting only. */ |
|
void AddOneShot(plOneShotMod *oneshot); |
|
void RemoveOneShot(plOneShotMod *oneshot); |
|
plOneShotMod *FindOneShot(const plString &name); |
|
// \} |
|
|
|
plKey LoadPlayer(const char* name, const char *account); |
|
plKey LoadPlayer(const char* name, const char *account, const char *linkName); |
|
plKey LoadAvatar(const char *name, const char *accountName, bool isPlayer, plKey spawnPoint, plAvTask *initialTask, const char *userStr = nil); |
|
|
|
/** |
|
* Unload an avatar clone |
|
* |
|
* This unloads the clone of an avatar (remote player or NPC) from our local game. |
|
* The avatar clone can be unloaded globally by setting netPropagate; however, this |
|
* is highly discouraged. |
|
*/ |
|
void UnLoadAvatar(const plKey& avKey, bool isPlayer, bool netPropagate=false) const; |
|
/** send our (already loaded) local player to newly-associated clients - used when linking */ |
|
void PropagateLocalPlayer(int spawnPoint = -1); |
|
/** Unload our local player on other machines because we're leaving this age. |
|
The player will stay around on our local machine, though. */ |
|
bool UnPropagateLocalPlayer(); |
|
|
|
void UnLoadLocalPlayer(); |
|
|
|
void AddAvatar(plArmatureMod *avatar); |
|
void RemoveAvatar(plArmatureMod *instance); |
|
|
|
plArmatureMod *GetLocalAvatar(); |
|
plKey GetLocalAvatarKey(); |
|
static plArmatureMod *FindAvatar(plKey& avatarKey); // Key of the sceneObject |
|
plArmatureMod *FindAvatarByPlayerID(uint32_t pid); |
|
plArmatureMod *FindAvatarByModelName(char *name); // Probably only useful for custom NPCs. All players are |
|
// either "Male" or "Female". |
|
void FindAllAvatarsByModelName(const char* name, plArmatureModPtrVec& outVec); |
|
plArmatureMod *GetFirstRemoteAvatar(); |
|
|
|
// \{ |
|
/** Spawn points are potential entry points for the |
|
avatar. They're selected pretty randomly right now; |
|
eventually they'll be selected by script based |
|
on the book used to enter the scene. */ |
|
void AddSpawnPoint(plSpawnModifier *spawn); |
|
void RemoveSpawnPoint(plSpawnModifier *spawn); |
|
const plSpawnModifier *GetSpawnPoint(int index); |
|
int NumSpawnPoints() { return fSpawnPoints.size(); } |
|
int FindSpawnPoint( const char *name ) const; |
|
// \} |
|
static int WarpPlayerToAnother(bool iMove, uint32_t remoteID); |
|
static int WarpPlayerToXYZ(float x, float y, float z); |
|
static int WarpPlayerToXYZ(int pid, float x, float y, float z); |
|
|
|
static plAvatarMgr *GetInstance(); |
|
static void ShutDown(); |
|
|
|
|
|
bool MsgReceive(plMessage *msg); |
|
bool HandleCoopMsg(plAvCoopMsg *msg); |
|
bool HandleNotifyMsg(plNotifyMsg *msg); |
|
bool IPassMessageToActiveCoop(plMessage *msg, uint32_t id, uint16_t serial); |
|
|
|
// similar to a spawn point, maintainers markers are used |
|
// to generate your position in Dni coordinates |
|
void AddMaintainersMarker(plMaintainersMarkerModifier *mm); |
|
void RemoveMaintainersMarker(plMaintainersMarkerModifier *mm); |
|
void PointToDniCoordinate(hsPoint3 pt, plDniCoordinateInfo* ret); |
|
void GetDniCoordinate(plDniCoordinateInfo* ret); |
|
|
|
static void OfferLinkingBook(plKey hostKey, plKey guestKey, plMessage *linkMsg, plKey replyKey); |
|
|
|
bool IsACoopRunning(); |
|
plStatusLog *GetLog() { return fLog; } |
|
|
|
protected: |
|
/** Dump all internal data. */ |
|
void IReset(); |
|
|
|
/** Handle an incoming clone message; do any necessary post-processing |
|
on the avatar. */ |
|
void IFinishLoadingAvatar(plLoadAvatarMsg *cloneMsg); |
|
|
|
/** Handle an incoming clone message which holds an unload request. |
|
*/ |
|
void IFinishUnloadingAvatar(plLoadAvatarMsg *cloneMsg); |
|
|
|
/** When an armature modifier attached to the given scene object is loaded, |
|
send it the given message. |
|
We get notified when the avatar's scene object is loaded, but we also need to |
|
set some information up for the avatar modifier when it comes in. |
|
We'll get that notification via the AddAvatar call later. In this function |
|
we're going to squirrel away an initialization message to pass to the armature |
|
modifier when it arrives. */ |
|
void IDeferInit(plKey playerSOKey, plMessage *initMsg); |
|
|
|
/** See if we have an avatar type message saved for the given avatar and send them. */ |
|
void ISendDeferredInit(plKey playerSOKey); |
|
|
|
static plAvatarMgr* fInstance; // the single instance of the avatar manager |
|
|
|
typedef std::map<plString, plSeekPointMod *, plString::less_i> plSeekPointMap; |
|
plSeekPointMap fSeekPoints; |
|
|
|
typedef std::map<plString, plOneShotMod *, plString::less_i> plOneShotMap; |
|
plOneShotMap fOneShots; |
|
|
|
typedef std::map<plKey, plMessage *> DeferredInits; |
|
DeferredInits fDeferredInits; |
|
|
|
// typedef std::map<const char *, plArmatureMod *, stringISorter> plAvatarMap; |
|
typedef std::vector<plKey> plAvatarVec; |
|
plAvatarVec fAvatars; |
|
|
|
typedef std::vector<const plSpawnModifier*> plSpawnVec; |
|
plSpawnVec fSpawnPoints; |
|
|
|
hsTArray<plMaintainersMarkerModifier*> fMaintainersMarkers; |
|
|
|
// we're using a multimap, which is a map which allows multiple entries to |
|
// share the same key. the key we use is the initiator's player id; in the vast |
|
// majority of cases, there will only be one coop running for a given initiator's |
|
// ID. By using a multimap, however, we can still handle a few different coops |
|
// for the same user by just iterating from the first match forward until |
|
// we run out of matches. |
|
typedef std::multimap<uint32_t, plCoopCoordinator *> plCoopMap; |
|
plCoopMap fActiveCoops; |
|
|
|
hsTArray<plLoadCloneMsg*> fCloneMsgQueue; |
|
plStatusLog *fLog; |
|
}; |
|
|
|
|
|
#endif // PLAVATARMGR_INC |
|
|
|
|