00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00023 #if !defined(AFX_CSPELL_H__08D0B2E9_9DDB_4F52_B2A8_8847149A4EAB__INCLUDED_)
00024 #define AFX_CSPELL_H__08D0B2E9_9DDB_4F52_B2A8_8847149A4EAB__INCLUDED_
00025
00026 #if _MSC_VER > 1000
00027 #pragma once
00028 #endif // _MSC_VER > 1000
00029 #include <winsock2.h>
00030 #include "Shared.h"
00031 #include "Message.h"
00032 #include "Client.h"
00033 #include "WorldManager.h"
00034 #include "MasterServer.h"
00035
00036 class cSpell
00037 {
00038 friend class cMasterServer;
00039 public:
00040 cSpell( DWORD dwSpellID, BOOL fAddToHash = TRUE )
00041 : m_dwSpellID( dwSpellID ),
00042 m_pcPrev ( NULL ),
00043 m_pcNext ( NULL )
00044 {
00045 m_dwIconID = 0x0L;
00046 m_dwEffect = 0x0L;
00047 m_fResearchable = false;
00048 m_dwManaCost = 0x0L;
00049 m_flUnkFloat1 = 0.0f;
00050 m_flUnkFloat2 = 0.0f;
00051 m_dwDifficulty = 0x0L;
00052 m_fEconomy = false;
00053 m_flSpeed = 0;
00054 m_dwType = 0x0L;
00055 m_iDuration = 0;
00056 for (int i = 0; i < 9; i++)
00057 m_dwComponents[i] = 0x0L;
00058 m_dwEffectAnim = 0x0L;
00059 m_dwLevel = 0x0L;
00060
00061 if( fAddToHash )
00062 Hash_Add( this );
00063 }
00064
00065 virtual ~cSpell()
00066 {
00067 if ( m_pcPrev ) m_pcPrev->m_pcNext = m_pcNext;
00068 else m_lpcHashTable[m_dwSpellID] = m_pcNext;
00069 if ( m_pcNext ) m_pcNext->m_pcPrev = m_pcPrev;
00070 }
00071
00072 static inline void Hash_Load( )
00073 {
00074 ZeroMemory( m_lpcHashTable, sizeof( m_lpcHashTable ) );
00075 }
00076
00077 static inline cSpell *Hash_New( DWORD& dwSpellID )
00078 {
00079 cSpell *pcSpell = Hash_Find( dwSpellID );
00080 if ( pcSpell )
00081 return pcSpell;
00082
00083 return new cSpell( dwSpellID ) ;
00084 }
00085
00086 static void Hash_Erase ( );
00087 static void Hash_Remove ( cSpell *pcSpell );
00088 static cSpell *FindSpell ( DWORD dwSpellID );
00089
00090 BYTE GetWindup ( );
00091 int GetWindupDelay ( );
00092 BYTE GetCastAnim ( );
00093 int GetCastAnimDelay ( );
00094 cMessage GetCastWords( );
00095
00096 DWORD m_dwSpellID;
00097 std::string m_strName;
00098 std::string m_strDesc;
00099 std::string m_strSchool;
00100 DWORD m_dwIconID;
00101 DWORD m_dwEffect;
00102 BOOL m_fResearchable;
00103 DWORD m_dwManaCost;
00104 float m_flUnkFloat1;
00105 float m_flUnkFloat2;
00106 DWORD m_dwDifficulty;
00107 BOOL m_fEconomy;
00108 float m_flSpeed;
00109 DWORD m_dwType;
00110 int m_iDuration;
00111 DWORD m_dwComponents[9];
00112 DWORD m_dwEffectAnim;
00113 DWORD m_dwLevel;
00114
00115 cSpell *m_pcNext;
00116 cSpell *m_pcPrev;
00117
00118 private:
00119 static cSpell *m_lpcHashTable[3000];
00120
00121 static inline Hash_Add( cSpell *pcSpell )
00122 {
00123 const DWORD dwSpellID = pcSpell->m_dwSpellID;
00124 if ( !m_lpcHashTable[dwSpellID] )
00125 m_lpcHashTable[dwSpellID] = pcSpell;
00126 else
00127 {
00128 pcSpell->m_pcNext = m_lpcHashTable[dwSpellID];
00129 m_lpcHashTable[dwSpellID]->m_pcPrev = pcSpell;
00130 m_lpcHashTable[dwSpellID] = pcSpell;
00131 }
00132 }
00133
00134
00135 static inline cSpell *Hash_Find( DWORD& dwSpellID )
00136 {
00137 const DWORD dwSpell = dwSpellID;
00138 cSpell *pcSpell = m_lpcHashTable[dwSpell];
00139 while ( pcSpell )
00140 {
00141 if ( pcSpell->CompareSpell( dwSpellID ) ) return pcSpell;
00142 else
00143 pcSpell = pcSpell->m_pcNext;
00144 }
00145 return NULL;
00146 }
00147
00148
00149 inline BOOL CompareSpell( DWORD& dwSpellID )
00150 {
00151 if ( dwSpellID == m_dwSpellID )
00152 return true;
00153 else
00154 return false;
00155 }
00156 };
00157
00158 class cSpellComp
00159 {
00160 friend class cMasterServer;
00161 friend class cSpell;
00162 public:
00163 cSpellComp( DWORD dwCompID, BOOL fAddToHash = TRUE )
00164 : m_dwCompID( dwCompID ),
00165 m_pcPrev ( NULL ),
00166 m_pcNext ( NULL )
00167 {
00168 m_dwIconID = 0x0L;
00169 m_flChargeID = 0.0f;
00170 m_flBurnRate = 0.0f;
00171 m_dwAnimID = 0x0L;
00172
00173 if( fAddToHash )
00174 Hash_Add( this );
00175 }
00176
00177 virtual ~cSpellComp()
00178 {
00179 if ( m_pcPrev ) m_pcPrev->m_pcNext = m_pcNext;
00180 else m_lpcHashTable[m_dwCompID] = m_pcNext;
00181 if ( m_pcNext ) m_pcNext->m_pcPrev = m_pcPrev;
00182 }
00183
00184 static inline void Hash_Load( )
00185 {
00186 ZeroMemory( m_lpcHashTable, sizeof( m_lpcHashTable ) );
00187 }
00188
00189 static inline cSpellComp *Hash_New( DWORD& dwCompID )
00190 {
00191 cSpellComp *pcComp = Hash_Find( dwCompID );
00192 if ( pcComp )
00193 return pcComp;
00194
00195 return new cSpellComp( dwCompID ) ;
00196 }
00197
00198 static void Hash_Erase ( );
00199 static void Hash_Remove ( cSpellComp *pcComp );
00200 static cSpellComp *FindComp ( DWORD dwCompID );
00201
00202 DWORD m_dwCompID;
00203 std::string m_strName;
00204 std::string m_strType;
00205 std::string m_strWords;
00206 DWORD m_dwIconID;
00207 float m_flChargeID;
00208 float m_flBurnRate;
00209 DWORD m_dwAnimID;
00210
00211 cSpellComp *m_pcNext;
00212 cSpellComp *m_pcPrev;
00213
00214 private:
00215 static cSpellComp *m_lpcHashTable[200];
00216
00217 static inline Hash_Add( cSpellComp *pcComp )
00218 {
00219 const DWORD dwCompID = pcComp->m_dwCompID;
00220 if ( !m_lpcHashTable[dwCompID] )
00221 m_lpcHashTable[dwCompID] = pcComp;
00222 else
00223 {
00224 pcComp->m_pcNext = m_lpcHashTable[dwCompID];
00225 m_lpcHashTable[dwCompID]->m_pcPrev = pcComp;
00226 m_lpcHashTable[dwCompID] = pcComp;
00227 }
00228 }
00229
00230
00231 static inline cSpellComp *Hash_Find( DWORD& dwCompID )
00232 {
00233 const DWORD dwComp = dwCompID;
00234 cSpellComp *pcComp = m_lpcHashTable[dwComp];
00235 while ( pcComp )
00236 {
00237 if ( pcComp->CompareComp( dwCompID ) ) return pcComp;
00238 else
00239 pcComp = pcComp->m_pcNext;
00240 }
00241 return NULL;
00242 }
00243
00244
00245 inline BOOL CompareComp( DWORD& dwCompID )
00246 {
00247 if ( dwCompID == m_dwCompID )
00248 return true;
00249 else
00250 return false;
00251 }
00252 };
00253
00254 class cEnchantment
00255 {
00256
00257 public:
00258 cEnchantment( DWORD dwSpellID, WORD wFamily, DWORD dwDifficulty, double dDuration, DWORD dwCasterGUID, DWORD dwTargetGUID, double dCastTime, DWORD dwFlags, DWORD dwKey, float flValue )
00259 : m_dwSpellID ( dwSpellID ),
00260 m_wFamily ( wFamily ),
00261 m_dwDifficulty ( dwDifficulty ),
00262 m_dDuration ( dDuration ),
00263 m_dwCasterGUID ( dwCasterGUID ),
00264 m_dwTargetGUID ( dwTargetGUID ),
00265 m_dCastTime ( dCastTime ),
00266 m_dwFlags ( dwFlags ),
00267 m_dwKey ( dwKey ),
00268 m_flValue ( flValue )
00269 {
00270 m_wLayer = 0x0001;
00271 m_wUnknown0 = 0x0000;
00272 m_dwUnknown1 = 0x0L;
00273 m_dwUnknown2 = 0x0L;
00274 m_dwUnknown3 = 0x0L;
00275
00276 cObject *pcObject = cWorldManager::FindObject( m_dwTargetGUID );
00277
00278 if (pcObject)
00279 {
00280 for ( iterEnchantment_lst itEnchantment = pcObject->m_lstEnchantments.begin( ); itEnchantment != pcObject->m_lstEnchantments.end( ); ++itEnchantment )
00281 {
00282 if ( (*itEnchantment)->m_dwSpellID == m_dwSpellID && (*itEnchantment)->m_wLayer >= m_wLayer )
00283 m_wLayer = (*itEnchantment)->m_wLayer + 1;
00284 }
00285
00286 pcObject->m_lstEnchantments.push_back( this );
00287 cMasterServer::m_lstEnchantments.push_back( this );
00288 }
00289 else
00290 {
00291 cClient *pcClient = cClient::FindClient( m_dwTargetGUID );
00292
00293 if (pcClient)
00294 {
00295 for ( iterEnchantment_lst itEnchantment = pcClient->m_pcAvatar->m_lstEnchantments.begin( ); itEnchantment != pcClient->m_pcAvatar->m_lstEnchantments.end( ); ++itEnchantment )
00296 {
00297 if ( (*itEnchantment)->m_dwSpellID == m_dwSpellID && (*itEnchantment)->m_wLayer >= m_wLayer )
00298 m_wLayer = (*itEnchantment)->m_wLayer + 1;
00299 }
00300
00301 pcClient->m_pcAvatar->m_lstEnchantments.push_back( this );
00302 cMasterServer::m_lstEnchantments.push_back( this );
00303 pcClient->AddPacket( WORLD_SERVER, pcClient->m_pcAvatar->AddEnchant( ++pcClient->m_dwF7B0Sequence, m_dwSpellID, m_wLayer, m_wFamily, m_dwDifficulty, m_dDuration, m_dwCasterGUID, m_dCastTime, m_dwFlags, m_dwKey, m_flValue ), 4);
00304 }
00305 }
00306 }
00307
00308 ~cEnchantment()
00309 {
00310 cObject *pcObject = cWorldManager::FindObject( m_dwTargetGUID );
00311
00312 if (pcObject)
00313 {
00314 for ( iterEnchantment_lst itEnchantment = pcObject->m_lstEnchantments.begin(); itEnchantment != pcObject->m_lstEnchantments.end( ); ++itEnchantment )
00315 {
00316 if ( (*itEnchantment)->m_dwSpellID == m_dwSpellID && (*itEnchantment)->m_wLayer == m_wLayer )
00317 {
00318 pcObject->m_lstEnchantments.erase( itEnchantment );
00319 itEnchantment = pcObject->m_lstEnchantments.end();
00320 }
00321 }
00322 }
00323 else
00324 {
00325 cClient *pcClient = cClient::FindClient( m_dwTargetGUID );
00326
00327 if (pcClient)
00328 {
00329 for ( iterEnchantment_lst itEnchantment = pcClient->m_pcAvatar->m_lstEnchantments.begin(); itEnchantment != pcClient->m_pcAvatar->m_lstEnchantments.end( ); ++itEnchantment )
00330 {
00331 if ( (*itEnchantment)->m_dwSpellID == m_dwSpellID && (*itEnchantment)->m_wLayer >= m_wLayer )
00332 {
00333 pcClient->m_pcAvatar->m_lstEnchantments.erase( itEnchantment );
00334 itEnchantment = pcClient->m_pcAvatar->m_lstEnchantments.end();
00335 }
00336 }
00337 pcClient->AddPacket( WORLD_SERVER, pcClient->m_pcAvatar->RemoveEnchant( ++pcClient->m_dwF7B0Sequence, m_dwSpellID, m_wLayer ), 4);
00338 }
00339 }
00340 }
00341
00342 DWORD m_dwSpellID;
00343 WORD m_wLayer;
00344 WORD m_wFamily;
00345 WORD m_wUnknown0;
00346 DWORD m_dwDifficulty;
00347 double m_dDuration;
00348 DWORD m_dwCasterGUID;
00349 DWORD m_dwTargetGUID;
00350 DWORD m_dwUnknown1;
00351 DWORD m_dwUnknown2;
00352 double m_dCastTime;
00353 DWORD m_dwFlags;
00354 DWORD m_dwKey;
00355 float m_flValue;
00356 DWORD m_dwUnknown3;
00357 };
00358
00359 #endif // !defined(AFX_CSPELL_H__08D0B2E9_9DDB_4F52_B2A8_8847149A4EAB__INCLUDED_)