Planeshift
|
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 §or) 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*> ®ions); 00219 00220 psWorld* GetWorld() const 00221 { 00222 return gameWorld; 00223 } 00224 00229 void HandleUnresolvedPos(GEMClientObject* entity, const csVector3 &pos, const csVector3 &rot, const csString §or); 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* §or); 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