Planeshift

pscelclient.h

Go to the documentation of this file.
00001 /*
00002  * pscelclient.h                by Matze Braun <[email protected]>
00003  *
00004  * Copyright (C) 2002-2009 Atomic Blue ([email protected], http://www.atomicblue.org)
00005  *
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation (version 2 of the License)
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017  *
00018  */
00019 #ifndef __psCelClient_H__
00020 #define __psCelClient_H__
00021 //=============================================================================
00022 // Crystal Space Includes
00023 //=============================================================================
00024 #include <csutil/cscolor.h>
00025 #include <csutil/parray.h>
00026 #include <csutil/refarr.h>
00027 #include <csutil/list.h>
00028 #include <csutil/hash.h>
00029 #include <csutil/redblacktree.h>
00030 #include <csutil/strhashr.h>
00031 #include <iengine/collection.h>
00032 #include <iengine/sector.h>
00033 #include <imesh/animesh.h>
00034 #include <imesh/animnode/skeleton2anim.h>
00035 #include <imesh/animnode/speed.h>
00036 
00037 //=============================================================================
00038 // Project Includes
00039 //=============================================================================
00040 
00041 #include "net/cmdbase.h"
00042 #include "engine/linmove.h"
00043 
00044 //=============================================================================
00045 // Local Includes
00046 //=============================================================================
00047 #include "psengine.h"
00048 
00049 struct Trait;
00050 struct iVFS;
00051 struct iSpriteCal3DState;
00052 struct iMeshObject;
00053 
00054 class MsgHandler;
00055 class psClientDR;
00056 class psNetPersist;
00057 class psClientVitals;
00058 class psCharAppearance;
00059 class psEntityLabels;
00060 class psShadowManager;
00061 class psWorld;
00062 class psPersistActor;
00063 class psPersistItem;
00064 class GEMClientObject;
00065 class GEMClientActor;
00066 class GEMClientItem;
00067 class GEMClientActionLocation;
00068 class psEffect;
00069 class psSolid;
00070 
00074 class UnresolvedPos
00075 {
00076 public:
00077     GEMClientObject* entity;   
00078 
00079     csVector3 pos;             
00080     csVector3 rot;
00081     csString sector;
00082 
00083     UnresolvedPos(GEMClientObject* entity, const csVector3 &pos, const csVector3 &rot, const csString &sector)
00084     {
00085         this->entity  = entity;
00086         this->pos     = pos;
00087         this->rot     = rot;
00088         this->sector  = sector;
00089     }
00090 };
00091 
00092 struct InstanceObject : public CS::Utility::FastRefCount<InstanceObject>
00093 {
00094     csRef<iMeshWrapper> pcmesh;
00095     csBox3 bbox;
00096     csWeakRefArray<iSector> sectors;
00097     csRef<iMeshFactoryWrapper> nullFactory;
00098     csRef<iThreadReturn> meshFact;
00099     csRef<iThreadReturn> material;
00100     ~InstanceObject();
00101 };
00102 
00106 class psCelClient : public psClientNetSubscriber
00107 {
00108 private:
00109     iObjectRegistry* object_reg;
00110     csPDelArray<GEMClientObject> entities;
00111     csHash<GEMClientObject*, EID> entities_hash;
00112     csRefArray<MsgEntry> newActorQueue;
00113     csRefArray<MsgEntry> newItemQueue;
00114     bool instantiateItems;
00115 
00116     // Keep seperate for speedups
00117     csArray<GEMClientActionLocation*> actions;
00118 
00119     struct Effect
00120     {
00121         csString effectname;
00122         csVector3 effectoffset;
00123         bool rotateWithMesh;
00124     };
00125 
00126     struct Light
00127     {
00128         csColor colour;
00129         csVector3 lightoffset;
00130         float radius;
00131     };
00132 
00133     struct ItemEffect
00134     {
00135         bool activeOnGround;
00136         csPDelArray<Effect> effects;
00137         csPDelArray<Light> lights;
00138     };
00139 
00140     csHash<ItemEffect*, csString> effectItems;
00141 
00143     void LoadEffectItems();
00144 
00145     csRedBlackTreeMap<csString, csRef<InstanceObject>,csFixedSizeAllocator<sizeof(CS::Container::RedBlackTreeNode<
00146             csRedBlackTreePayload<csString,csRef<InstanceObject> > >)>, CS::Container::RedBlackTreeOrderingStrictWeak > instanceObjects;
00147 
00148     csRedBlackTreeMap<csString, csRef<iMeshFactoryWrapper>,csFixedSizeAllocator<sizeof(CS::Container::RedBlackTreeNode<
00149             csRedBlackTreePayload<csString,csRef<iMeshFactoryWrapper> > >)>, CS::Container::RedBlackTreeOrderingStrictWeak > nullFactories;
00150 
00151 public:
00152 
00153     psCelClient();
00154     virtual ~psCelClient();
00155 
00156     bool Initialize(iObjectRegistry* object_reg, MsgHandler* msghandler);
00157 
00158     void RequestServerWorld();
00159     bool IsReady();
00160 
00161     GEMClientObject* FindObject(EID eid);
00162 
00163     void RequestActor();
00164     void SetMainActor(GEMClientActor* object);
00165     void SetPlayerReady(bool flag);
00166 
00167     void RemoveObject(GEMClientObject* entity);
00168 
00169     psClientDR* GetClientDR()
00170     {
00171         return clientdr;
00172     }
00173     const csPDelArray<GEMClientObject> &GetEntities() const
00174     {
00175         return entities;
00176     }
00177     bool IsMeshSubjectToAction(const char* sector,const char* mesh);
00178     GEMClientActor* GetActorByName(const char* name, bool trueName = true) const;
00179 
00180     virtual void HandleMessage(MsgEntry* me);
00181 
00182     void SetupWorldColliders();
00183 
00184     psEntityLabels* GetEntityLabels()
00185     {
00186         return entityLabels;
00187     }
00188     psShadowManager* GetShadowManager()
00189     {
00190         return shadowManager;
00191     }
00192 
00193     void SetMainPlayerName(const char* name)
00194     {
00195         player_name = name;
00196     }
00197 
00198     const char* GetMainPlayerName()
00199     {
00200         return player_name;
00201     }
00202 
00203     GEMClientActor* GetMainPlayer()
00204     {
00205         return local_player;
00206     }
00207 
00209     void HandleItemEffect(const char* factName, iMeshWrapper* mw, bool onGround = true, const char* slot = 0,
00210                           csHash<int, csString>* effectids = 0, csHash<int, csString>* lightids = 0);
00211 
00214     void OnMapsLoaded();
00215 
00218     void OnRegionsDeleted(csArray<iCollection*> &regions);
00219 
00220     psWorld* GetWorld() const
00221     {
00222         return gameWorld;
00223     }
00224 
00229     void HandleUnresolvedPos(GEMClientObject* entity, const csVector3 &pos, const csVector3 &rot, const csString &sector);
00230 
00231     void PruneEntities();
00232 
00233     bool IsUnresSector(iSector* sector)
00234     {
00235         return unresSector == sector;
00236     }
00237     iSector* GetUnresSector()
00238     {
00239         return unresSector;
00240     }
00241 
00242     int GetRequestStatus()
00243     {
00244         return requeststatus;
00245     }
00246 
00248     void CheckEntityQueues();
00250     void ForceEntityQueues();
00251 
00252     void Update(bool loaded);
00253 
00254 
00261     void AttachObject(iObject* object, GEMClientObject* clientObject);
00262 
00269     void UnattachObject(iObject* object, GEMClientObject* clientObject);
00270 
00277     GEMClientObject* FindAttachedObject(iObject* object);
00278 
00279 
00288     csArray<GEMClientObject*> FindNearbyEntities(iSector* sector, const csVector3 &pos, float radius, bool doInvisible = false);
00289 
00293     csPtr<InstanceObject> FindInstanceObject(const char* name) const;
00294 
00298     void AddInstanceObject(const char* name, csRef<InstanceObject> object);
00299 
00303     void RemoveInstanceObject(const char* name);
00304 
00305     csPtr<iMeshFactoryWrapper> FindNullFactory(const char* name) const;
00306     void AddNullFactory(const char* name, csRef<iMeshFactoryWrapper> object);
00307     void RemoveNullFactory(const char* name);
00308 
00313     void replaceRacialGroup(csString &string);
00314 
00315     bool InstanceItems()
00316     {
00317         return instantiateItems;
00318     }
00319 
00320 protected:
00322     csList<UnresolvedPos*>::Iterator FindUnresolvedPos(GEMClientObject* entity);
00323 
00324     int requeststatus;
00325     csRef<iVFS>         vfs;
00326     csRef<MsgHandler>   msghandler;
00327     psClientDR* clientdr;
00328 
00329     psEntityLabels* entityLabels;
00330     psShadowManager* shadowManager;
00331 
00332     psWorld* gameWorld;
00333 
00334     void HandleWorld(MsgEntry* me);
00335     void HandleActor(MsgEntry* me);
00336     void HandleItem(MsgEntry* me);
00337     void HandleActionLocation(MsgEntry* me);
00338     void HandleObjectRemoval(MsgEntry* me);
00339     void HandleNameChange(MsgEntry* me);
00340     void HandleGuildChange(MsgEntry* me);
00341     void HandleGroupChange(MsgEntry* me);
00342 
00343     void HandleMecsActivate(MsgEntry* me);
00344 
00345     void AddEntity(GEMClientObject* obj);
00346 
00350     void HandleStats(MsgEntry* me);
00351 
00352     GEMClientActor* local_player;
00353     csString player_name;              
00354 
00355     csList<UnresolvedPos*> unresPos;   
00356     csRef<iSector> unresSector;        
00357 };
00358 
00359 enum GEMOBJECT_TYPE
00360 {
00361     GEM_OBJECT = 0,
00362     GEM_ACTOR,
00363     GEM_ITEM,
00364     GEM_ACTION_LOC,
00365     GEM_TYPE_COUNT
00366 };
00367 
00371 class GEMClientObject : public DelayedLoader
00372 {
00373 public:
00374     GEMClientObject();
00375     GEMClientObject(psCelClient* cel, EID id);
00376     virtual ~GEMClientObject();
00377 
00378     virtual GEMOBJECT_TYPE GetObjectType()
00379     {
00380         return GEM_OBJECT;
00381     }
00382 
00384     void SubstituteRacialMeshFact();
00385 
00387     void LoadMesh();
00388 
00394     void Move(const csVector3 &pos, const csVector3 &rotangle, const char* room);
00395 
00401     void Rotate(float xRot, float yRot, float zRot);
00402 
00404     virtual void SetPosition(const csVector3 &pos, const csVector3 &rot, iSector* sector);
00405 
00407     virtual csVector3 GetPosition();
00408 
00414     virtual float GetRotation();
00415 
00417     virtual iSector* GetSector() const;
00418 
00420     virtual iSectorList* GetSectors() const;
00421 
00423     virtual const csBox3 &GetBBox() const;
00424 
00425     EID GetEID()
00426     {
00427         return eid;
00428     }
00429     csRef<iMeshWrapper> pcmesh;
00430 
00431     virtual int GetMasqueradeType();
00432 
00433     int GetType()
00434     {
00435         return type;
00436     }
00437 
00438     virtual const char* GetName()
00439     {
00440         return name;
00441     }
00442     virtual void ChangeName(const char* name);
00443 
00444     const char* GetFactName()
00445     {
00446         return factName;
00447     }
00448 
00449     psEffect* GetEntityLabel()
00450     {
00451         return entitylabel;
00452     }
00453     void      SetEntityLabel(psEffect* el)
00454     {
00455         entitylabel = el;
00456     }
00457 
00458     psEffect* GetShadow()
00459     {
00460         return shadow;
00461     }
00462     void SetShadow(psEffect* shadow)
00463     {
00464         this->shadow = shadow;
00465     }
00466 
00470     virtual bool IsAlive()
00471     {
00472         return false;
00473     }
00474 
00478     int Flags()
00479     {
00480         return flags;
00481     }
00482 
00486     iMeshWrapper* GetMesh() const;
00487 
00488     virtual void Update();
00489 
00490     float RangeTo(GEMClientObject* obj, bool ignoreY);
00491 
00492     bool HasShadow() const
00493     {
00494         return hasShadow;
00495     }
00496 
00497     bool HasLabel() const
00498     {
00499         return hasLabel;
00500     }
00501 
00505     virtual bool CheckLoadStatus()
00506     {
00507         return false;
00508     }
00509 
00513     virtual void PostLoad(bool /*nullmesh*/) { }
00514 
00515     /* we need to invoke this when we destroy the celClient itself, so the reference to the (now gone) celClient gets unset.
00516      * Never call this from any other place, since it will unset the celClient reference for *all* GEMClientObjects
00517      */
00518     static void UnsetCelClient()
00519     {
00520         cel = NULL;
00521     }
00522 
00523 protected:
00524     static psCelClient* cel;
00525 
00526     csString name;
00527     csString factName;
00528     csString matName;
00529     EID eid;
00530     int type;
00531 
00532     int flags;                      
00533     psEffect* entitylabel;
00534     psEffect* shadow;
00535     bool hasLabel;
00536     bool hasShadow;
00537 
00538     csRef<InstanceObject> instance;
00539     csRef<csShaderVariable> position;
00540 };
00541 
00542 class psDRMessage;
00543 
00544 
00545 //---------------------------------------------------------------------------
00546 
00547 
00548 
00549 //--------------------------------------------------------------------------
00550 
00552 class GEMClientActor : public GEMClientObject
00553 {
00554 public:
00555 
00556     GEMClientActor(psCelClient* cel, psPersistActor &mesg);
00557     virtual ~GEMClientActor();
00558 
00559     virtual GEMOBJECT_TYPE GetObjectType()
00560     {
00561         return GEM_ACTOR;
00562     }
00563 
00571     void CopyNewestData(GEMClientActor &oldActor);
00572 
00579     void GetLastPosition(csVector3 &pos, float &yrot, iSector* &sector);
00580 
00585     const csVector3 GetVelocity() const;
00586 
00587     float GetYRotation() const;
00588 
00589     virtual void SetPosition(const csVector3 &pos, float rot, iSector* sector);
00590 
00593     void SetVelocity(const csVector3 &vel);
00594 
00597     void SetYRotation(const float yrot);
00598 
00599     void SetAlive(bool aliveFlag, bool newactor);
00600     virtual bool IsAlive()
00601     {
00602         return alive;
00603     }
00604     virtual int GetMasqueradeType()
00605     {
00606         return masqueradeType;
00607     }
00608 
00611     psClientVitals* GetVitalMgr()
00612     {
00613         return vitalManager;
00614     }
00615 
00616     csVector3 Pos() const;
00617     csVector3 Rot() const;
00618     iSector* GetSector() const;
00619 
00620     virtual const char* GetName(bool realName = true);
00621 
00622     const char* GetGuildName()
00623     {
00624         return guildName;
00625     }
00626     void SetGuildName(const char* guild)
00627     {
00628         guildName = guild;
00629     }
00630 
00631     bool NeedDRUpdate(unsigned char &priority);
00632     void SendDRUpdate(unsigned char priority,csStringHashReversible* msgstrings);
00633     void SetDRData(psDRMessage &drmsg);
00634     void StopMoving(bool worldVel = false);
00635 
00636     psCharAppearance* CharAppearance()
00637     {
00638         return charApp;
00639     }
00640 
00641     psLinearMovement* linmove;
00642 
00644     psClientVitals* vitalManager;
00645 
00646     void SetMode(uint8_t mode, bool newactor = false);
00647     uint8_t GetMode()
00648     {
00649         return serverMode;
00650     }
00651     void SetIdleAnimation(const char* anim);
00652     void SetAnimationVelocity(const csVector3 &velocity);
00653     bool SetAnimation(const char* anim, int duration=0);
00654     void RefreshCal3d();  
00655 
00656     void SetChatBubbleID(unsigned int chatBubbleID);
00657     unsigned GetChatBubbleID() const;
00658 
00659     csRef<iSpriteCal3DState> cal3dstate;
00660     csRef<CS::Mesh::iAnimatedMesh> animeshObject;
00661     csRef<CS::Animation::iSkeletonSpeedNode> speedNode;
00662 
00667     int GetAnimIndex(csStringHashReversible* msgstrings, csStringID animid);
00668 
00669     // The following hash is used by GetAnimIndex().
00670     csHash<int,csStringID> anim_hash;
00671 
00675     virtual bool CheckLoadStatus();
00676 
00677     csString race;
00678     csString partName;
00679     csString mountFactname;
00680     csString MounterAnim;
00681     csString helmGroup;
00682     csString BracerGroup;
00683     csString BeltGroup;
00684     csString CloakGroup;
00685     csString equipment;
00686     csString traits;
00687     csVector3 lastSentVelocity,lastSentRotation;
00688     bool stationary,path_sent;
00689     csTicks lastDRUpdateTime;
00690     unsigned short gender;
00691     float scale;
00692     float baseScale;
00693     float mountScale;
00694 
00695     // Access functions for the group var
00696     bool IsGroupedWith(GEMClientActor* actor);
00697     bool IsOwnedBy(GEMClientActor* actor);
00698     unsigned int GetGroupID()
00699     {
00700         return groupID;
00701     }
00702     void SetGroupID(unsigned int id)
00703     {
00704         groupID = id;
00705     }
00706     EID  GetOwnerEID()
00707     {
00708         return ownerEID;
00709     }
00710     void SetOwnerEID(EID id)
00711     {
00712         ownerEID = id;
00713     }
00714 
00715     csPDelArray<Trait> traitList;
00716 
00719     psLinearMovement &Movement();
00720 
00721     virtual void Update();
00722 
00723 protected:
00724     // keep track of allocated ressources
00725     csRef<iThreadReturn> factory;
00726     csRef<iThreadReturn> mountFactory;
00727     csRef<iMeshWrapper> rider;
00728 
00729     psCharAppearance* charApp;
00730 
00731     unsigned int chatBubbleID;
00732     unsigned int groupID;
00733     EID ownerEID;
00734     csString guildName;
00735     uint8_t  DRcounter;  
00736     bool DRcounter_set;
00737 
00738     virtual void SwitchToRealMesh(iMeshWrapper* mesh);
00739 
00740     void InitCharData(const char* textures, const char* equipment);
00741 
00742     bool alive;
00743 
00744     int masqueradeType;
00745 
00746     void SetCharacterMode(size_t id);
00747     size_t movementMode;
00748     uint8_t serverMode;
00749 
00751     struct PostLoadData
00752     {
00753         csVector3 pos;
00754         float yrot;
00755         csString sector_name;
00756         iSector* sector;
00757         csVector3 top;
00758         csVector3 bottom;
00759         csVector3 offset;
00760         csVector3 vel;
00761         csString texParts;
00762     };
00763 
00764     PostLoadData* post_load;
00765 };
00766 
00768 class GEMClientItem : public GEMClientObject
00769 {
00770 public:
00771     GEMClientItem(psCelClient* cel, psPersistItem &mesg);
00772     virtual ~GEMClientItem();
00773 
00774     virtual GEMOBJECT_TYPE GetObjectType()
00775     {
00776         return GEM_ITEM;
00777     }
00778 
00782     virtual bool CheckLoadStatus();
00783 
00784 protected:
00785     virtual void PostLoad();
00787     csPtr<iMaterialWrapper> CloneMaterial(iMaterialWrapper* material);
00788 
00789     psSolid* solid;
00790 
00791 private:
00793     struct PostLoadData
00794     {
00795         csVector3 pos;
00796         float xRot;
00797         float yRot;
00798         float zRot;
00799         csString sector;
00800     };
00801 
00802     PostLoadData* post_load;
00803     csRef<iThreadReturn> factory;
00804     csRef<iThreadReturn> material;
00805     csRef<iShaderManager> shman;
00806     csRef<iStringSet> strings;
00807 };
00808 
00810 class GEMClientActionLocation : public GEMClientObject
00811 {
00812 public:
00813     GEMClientActionLocation(psCelClient* cel, psPersistActionLocation &mesg);
00814 
00815     virtual GEMOBJECT_TYPE GetObjectType()
00816     {
00817         return GEM_ACTION_LOC;
00818     }
00819 
00820     const char* GetMeshName()
00821     {
00822         return meshname;
00823     }
00824 
00825 protected:
00826     csString meshname;
00827 };
00828 
00829 #endif
00830