Clone of PhatAC @ https://github.com/floaterxk/PhatAC

ObjectMsgs.cpp 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. #include "StdAfx.h"
  2. #include "PhysicsObj.h"
  3. #include "Monster.h"
  4. #include "Player.h"
  5. #include "Item.h"
  6. //Network access.
  7. #include "Client.h"
  8. #include "BinaryWriter.h"
  9. #include "ObjectMsgs.h"
  10. #define MESSAGE_BEGIN(x) BinaryWriter *x = new BinaryWriter
  11. #define MESSAGE_END(x) return x
  12. BinaryWriter *GetWeenieObjData(CPhysicsObj *pEntity)
  13. {
  14. BinaryWriter OptionalWeenieObjData;
  15. DWORD dwSections = 0;
  16. if (pEntity->Container_HasContents())
  17. {
  18. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_ItemsCapacity;
  19. OptionalWeenieObjData.WriteBYTE(pEntity->Container_MaxInventorySlots()); // item capacity
  20. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_ContainersCapacity;
  21. OptionalWeenieObjData.WriteBYTE(pEntity->Container_MaxContainerSlots()); // container capacity
  22. }
  23. if (pEntity->m_AmmoType != 0)
  24. {
  25. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_AmmoType;
  26. OptionalWeenieObjData.WriteWORD(pEntity->m_AmmoType);
  27. }
  28. if (pEntity->m_Value != 0)
  29. {
  30. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_Value;
  31. OptionalWeenieObjData.WriteDWORD(pEntity->m_Value);
  32. }
  33. if (pEntity->m_Usability != 0)
  34. {
  35. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_Useability;
  36. OptionalWeenieObjData.WriteDWORD((DWORD)pEntity->m_Usability);
  37. }
  38. float flApproachDist = pEntity->GetApproachDist();
  39. if (flApproachDist > 0.0f)
  40. {
  41. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_UseRadius;
  42. OptionalWeenieObjData.WriteFloat(flApproachDist);
  43. }
  44. if (pEntity->m_TargetType != 0)
  45. {
  46. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_TargetType;
  47. OptionalWeenieObjData.WriteDWORD(pEntity->m_TargetType);
  48. }
  49. if (pEntity->m_UIEffects)
  50. {
  51. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_UIEffects;
  52. OptionalWeenieObjData.WriteDWORD(pEntity->m_UIEffects);
  53. }
  54. if (pEntity->HasEquipType())
  55. {
  56. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_CombatUse;
  57. OptionalWeenieObjData.WriteBYTE((BYTE)pEntity->GetEquipType());
  58. }
  59. if (pEntity->IsContained())
  60. {
  61. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_ContainerID;
  62. OptionalWeenieObjData.WriteDWORD(pEntity->GetContainerID());
  63. }
  64. if (pEntity->HasCoverage())
  65. {
  66. CBaseItem *pItem = (CBaseItem*)pEntity;
  67. DWORD dwCoverage1 = pItem->GetCoverage1();
  68. DWORD dwCoverage2 = pItem->GetCoverage2();
  69. DWORD dwCoverage3 = pItem->GetCoverage3();
  70. if (dwCoverage1)
  71. {
  72. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_ValidLocations;
  73. OptionalWeenieObjData.WriteDWORD(dwCoverage1);
  74. }
  75. if (dwCoverage2)
  76. {
  77. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_Location;
  78. OptionalWeenieObjData.WriteDWORD(dwCoverage1);
  79. }
  80. if (dwCoverage3)
  81. {
  82. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_Priority;
  83. OptionalWeenieObjData.WriteDWORD(dwCoverage1);
  84. }
  85. }
  86. if (pEntity->m_BlipColor != 0)
  87. {
  88. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_BlipColor;
  89. OptionalWeenieObjData.WriteBYTE(pEntity->m_BlipColor);
  90. }
  91. if (pEntity->m_RadarVis != 0)
  92. {
  93. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_RadarEnum;
  94. OptionalWeenieObjData.WriteBYTE((BYTE)pEntity->m_RadarVis);
  95. }
  96. if (pEntity->HasBurden())
  97. {
  98. dwSections |= PublicWeenieDescPackHeader::PWD_Packed_Burden;
  99. OptionalWeenieObjData.WriteWORD(pEntity->m_Burden);
  100. }
  101. BinaryWriter *WeenieObjData = new BinaryWriter;
  102. WeenieObjData->WriteDWORD(dwSections);
  103. WeenieObjData->WriteString(pEntity->GetName());
  104. WeenieObjData->WriteWORD(pEntity->m_wTypeID);
  105. WeenieObjData->WriteWORD(pEntity->m_wIcon);
  106. WeenieObjData->WriteDWORD(pEntity->m_ItemType);
  107. WeenieObjData->WriteDWORD(pEntity->m_WeenieBitfield);
  108. WeenieObjData->AppendData(OptionalWeenieObjData.GetData(), OptionalWeenieObjData.GetSize());
  109. return WeenieObjData;
  110. }
  111. BinaryWriter *GetPhysicsObjData(CPhysicsObj *pEntity)
  112. {
  113. BinaryWriter OptionalPhysicsObjData;
  114. DWORD dwSections = 0; //0x019803
  115. if (pEntity->m_dwAnimationSet)
  116. {
  117. dwSections |= PhysicsDescInfo::MOVEMENT;
  118. if (!pEntity->m_AnimOverrideData)
  119. {
  120. BinaryWriter *AnimInfo = pEntity->Animation_GetAnimationInfo();
  121. OptionalPhysicsObjData.WriteDWORD(AnimInfo->GetSize());
  122. OptionalPhysicsObjData.AppendData(AnimInfo->GetData(), AnimInfo->GetSize());
  123. OptionalPhysicsObjData.WriteDWORD(pEntity->m_AutonomousMovement); // autonomous movement?
  124. delete AnimInfo;
  125. }
  126. else
  127. {
  128. OptionalPhysicsObjData.WriteDWORD(pEntity->m_AnimOverrideDataLen);
  129. OptionalPhysicsObjData.AppendData(pEntity->m_AnimOverrideData, pEntity->m_AnimOverrideDataLen);
  130. OptionalPhysicsObjData.WriteDWORD(pEntity->m_AutonomousMovement);
  131. }
  132. }
  133. else if (pEntity->CanPickup())
  134. {
  135. dwSections |= PhysicsDescInfo::ANIMFRAME_ID;
  136. OptionalPhysicsObjData.WriteDWORD(0x00000065); // animation frame ID????
  137. }
  138. if (!pEntity->HasOwner())
  139. {
  140. dwSections |= PhysicsDescInfo::POSITION;
  141. OptionalPhysicsObjData.AppendData(&pEntity->m_Origin, sizeof(loc_t));
  142. OptionalPhysicsObjData.AppendData(&pEntity->m_Angles, sizeof(heading_t));
  143. }
  144. if (pEntity->m_dwAnimationSet)
  145. {
  146. dwSections |= PhysicsDescInfo::MTABLE;
  147. OptionalPhysicsObjData.WriteDWORD(pEntity->m_dwAnimationSet);
  148. }
  149. DWORD dwSoundSet = pEntity->GetSoundSet();
  150. if (dwSoundSet)
  151. {
  152. dwSections |= PhysicsDescInfo::STABLE;
  153. OptionalPhysicsObjData.WriteDWORD(dwSoundSet);
  154. }
  155. DWORD dwEffectSet = pEntity->GetEffectSet();
  156. if (dwEffectSet)
  157. {
  158. dwSections |= PhysicsDescInfo::PETABLE;
  159. OptionalPhysicsObjData.WriteDWORD(dwEffectSet);
  160. }
  161. DWORD dwModelNumber = pEntity->m_dwModel;
  162. if (dwModelNumber)
  163. {
  164. dwSections |= PhysicsDescInfo::CSetup;
  165. OptionalPhysicsObjData.WriteDWORD(dwModelNumber);
  166. }
  167. if (pEntity->IsWielded())
  168. {
  169. dwSections |= PhysicsDescInfo::PARENT;
  170. OptionalPhysicsObjData.WriteDWORD(pEntity->GetWielderID());
  171. OptionalPhysicsObjData.WriteDWORD(pEntity->GetEquipSlot());
  172. }
  173. ItemVector vItems;
  174. pEntity->Container_GetWieldedItems(&vItems);
  175. if (!vItems.empty())
  176. {
  177. DWORD dwEquippedCount = 0;
  178. BinaryWriter pEquipped;
  179. ItemVector::iterator iit = vItems.begin();
  180. ItemVector::iterator iend = vItems.end();
  181. while (iit != iend)
  182. {
  183. CBaseItem* pItem = *iit;
  184. if (pItem->HasEquipSlot())
  185. {
  186. pEquipped.WriteDWORD(pItem->m_dwGUID);
  187. pEquipped.WriteDWORD(pItem->GetEquipSlot());
  188. dwEquippedCount++;
  189. }
  190. iit++;
  191. }
  192. if (dwEquippedCount)
  193. {
  194. dwSections |= PhysicsDescInfo::CHILDREN;
  195. OptionalPhysicsObjData.WriteDWORD(dwEquippedCount);
  196. OptionalPhysicsObjData.AppendData(pEquipped.GetData(), pEquipped.GetSize());
  197. }
  198. }
  199. if (pEntity->m_fScale != 0.0f && pEntity->m_fScale != 1.0f)
  200. {
  201. dwSections |= PhysicsDescInfo::OBJSCALE;
  202. OptionalPhysicsObjData.WriteFloat(pEntity->m_fScale);
  203. }
  204. /*
  205. if (pEntity->m_Translucency != 0.0f)
  206. {
  207. dwSections |= PhysicsDescInfo::TRANSLUCENCY;
  208. OptionalPhysicsObjData.WriteFloat(pEntity->m_Translucency);
  209. }
  210. */
  211. BinaryWriter *PhysicsObjData = new BinaryWriter;
  212. PhysicsObjData->WriteDWORD(dwSections);
  213. PhysicsObjData->WriteDWORD(pEntity->m_PhysicsState); //VIS flags
  214. PhysicsObjData->AppendData(OptionalPhysicsObjData.GetData(), OptionalPhysicsObjData.GetSize());
  215. //Moved from CO
  216. PhysicsObjData->WriteWORD(pEntity->m_wNumMovements);
  217. PhysicsObjData->WriteWORD(pEntity->m_wNumAnimInteracts);
  218. PhysicsObjData->WriteWORD(pEntity->m_wNumBubbleModes);
  219. PhysicsObjData->WriteWORD(pEntity->m_wNumJumps);
  220. PhysicsObjData->WriteWORD(pEntity->m_wNumPortals);
  221. PhysicsObjData->WriteWORD(pEntity->m_wAnimCount);
  222. PhysicsObjData->WriteWORD(pEntity->m_wNumOverride);
  223. PhysicsObjData->WriteWORD(pEntity->m_wNumModelChanges);
  224. PhysicsObjData->WriteWORD(pEntity->m_wInstance);
  225. PhysicsObjData->Align();
  226. return PhysicsObjData;
  227. }
  228. BinaryWriter *CreateObject(CPhysicsObj *pEntity)
  229. {
  230. BinaryWriter *CO = new BinaryWriter;
  231. CO->WriteDWORD(0xF745);
  232. CO->WriteDWORD(pEntity->m_dwGUID);
  233. BinaryWriter *ModelData = pEntity->GetModelData();
  234. CO->AppendData(ModelData->GetData(), ModelData->GetSize());
  235. delete ModelData;
  236. BinaryWriter *PhysicsObjData = GetPhysicsObjData(pEntity);
  237. CO->AppendData(PhysicsObjData->GetData(), PhysicsObjData->GetSize());
  238. delete PhysicsObjData;
  239. BinaryWriter *WeenieObjData = GetWeenieObjData(pEntity);
  240. CO->AppendData(WeenieObjData->GetData(), WeenieObjData->GetSize());
  241. delete WeenieObjData;
  242. CO->Align();
  243. return CO;
  244. }
  245. BinaryWriter *UpdateObject(CPhysicsObj *pEntity)
  246. {
  247. BinaryWriter *UO = new BinaryWriter;
  248. UO->WriteDWORD(0xF7DB);
  249. UO->WriteDWORD(pEntity->m_dwGUID);
  250. BinaryWriter *ModelData = pEntity->GetModelData();
  251. UO->AppendData(ModelData->GetData(), ModelData->GetSize());
  252. delete ModelData;
  253. pEntity->m_wNumModelChanges++;
  254. pEntity->m_wNumPortals++;
  255. pEntity->m_wNumAnimInteracts++;
  256. pEntity->m_wNumBubbleModes++;
  257. pEntity->m_wNumJumps++;
  258. pEntity->m_wNumMovements++;
  259. BinaryWriter *PhysicsObjData = GetPhysicsObjData(pEntity);
  260. UO->AppendData(PhysicsObjData->GetData(), PhysicsObjData->GetSize());
  261. delete PhysicsObjData;
  262. BinaryWriter *WeenieObjData = GetWeenieObjData(pEntity);
  263. UO->AppendData(WeenieObjData->GetData(), WeenieObjData->GetSize());
  264. delete WeenieObjData;
  265. UO->Align();
  266. return UO;
  267. }
  268. BinaryWriter *IdentifyObject_DwordData(CPhysicsObj *pEntity)
  269. {
  270. BinaryWriter *Dwords = new BinaryWriter;
  271. int DwordCount = 0;
  272. for (int i = 0; i < 0x100; i++) {
  273. DWORD dwValue = pEntity->m_dwStats[i];
  274. if (dwValue)
  275. {
  276. DwordCount++;
  277. Dwords->WriteDWORD(i);
  278. Dwords->WriteDWORD(dwValue);
  279. }
  280. }
  281. if (!DwordCount) {
  282. delete Dwords;
  283. return NULL;
  284. }
  285. BinaryWriter *DwordData = new BinaryWriter;
  286. DwordData->WriteWORD(DwordCount);
  287. DwordData->WriteWORD(0x40);
  288. DwordData->AppendData(Dwords->GetData(), Dwords->GetSize());
  289. delete Dwords;
  290. return DwordData;
  291. }
  292. BinaryWriter *IdentifyObject_StringData(CPhysicsObj *pEntity)
  293. {
  294. BinaryWriter *Strings = new BinaryWriter;
  295. WORD wStringCount = 0;
  296. const char* szDescription = pEntity->GetDescription();
  297. if (szDescription && (strlen(szDescription) > 0))
  298. {
  299. wStringCount++;
  300. Strings->WriteDWORD(0x10);
  301. Strings->WriteString(szDescription);
  302. }
  303. if (!wStringCount)
  304. {
  305. delete Strings;
  306. return NULL;
  307. }
  308. BinaryWriter *StringData = new BinaryWriter;
  309. StringData->WriteWORD(wStringCount);
  310. StringData->WriteWORD(0x10);
  311. StringData->AppendData(Strings->GetData(), Strings->GetSize());
  312. delete Strings;
  313. return StringData;
  314. }
  315. BinaryWriter *IdentifyObject_PlayerData(CPhysicsObj *pEntity)
  316. {
  317. if (!pEntity->IsPlayer())
  318. return NULL;
  319. CBasePlayer* pPlayer = (CBasePlayer *)pEntity;
  320. BinaryWriter *PlayerPoo = new BinaryWriter;
  321. DWORD dwContents = 5;
  322. if (pPlayer->IsHuman())
  323. dwContents |= 2;
  324. PlayerPoo->WriteDWORD(dwContents);
  325. if (dwContents & 4) {
  326. PlayerPoo->WriteDWORD(0/*pPlayer->GetObjectStat( eLevel )*/);
  327. PlayerPoo->WriteDWORD(0/*GetVitalCurrent( pPlayer->GetVitalData( eHealth ), 0 )*/);
  328. PlayerPoo->WriteDWORD(GetVitalMax(pPlayer->GetVitalData(eHealth), 0));
  329. }
  330. if (dwContents & 8) {
  331. PlayerPoo->WriteDWORD(GetAttributeMax(pPlayer->GetAttributeData(eStrength), 0));
  332. PlayerPoo->WriteDWORD(GetAttributeMax(pPlayer->GetAttributeData(eEndurance), 0));
  333. PlayerPoo->WriteDWORD(GetAttributeMax(pPlayer->GetAttributeData(eQuickness), 0));
  334. PlayerPoo->WriteDWORD(GetAttributeMax(pPlayer->GetAttributeData(eCoordination), 0));
  335. PlayerPoo->WriteDWORD(GetAttributeMax(pPlayer->GetAttributeData(eFocus), 0));
  336. PlayerPoo->WriteDWORD(GetAttributeMax(pPlayer->GetAttributeData(eSelf), 0));
  337. PlayerPoo->WriteDWORD(GetVitalCurrent(pPlayer->GetVitalData(eStamina), 0));
  338. PlayerPoo->WriteDWORD(GetVitalCurrent(pPlayer->GetVitalData(eMana), 0));
  339. PlayerPoo->WriteDWORD(GetVitalMax(pPlayer->GetVitalData(eStamina), 0));
  340. PlayerPoo->WriteDWORD(GetVitalMax(pPlayer->GetVitalData(eMana), 0));
  341. }
  342. PlayerPoo->WriteDWORD(0x1F);
  343. if (dwContents & 2) {
  344. PlayerPoo->WriteDWORD(pPlayer->GetObjectStat(eLevel));
  345. PlayerPoo->WriteDWORD(-1);
  346. PlayerPoo->WriteDWORD(1);
  347. PlayerPoo->WriteString(pPlayer->GetGenderString());
  348. PlayerPoo->WriteString(pPlayer->GetRaceString());
  349. PlayerPoo->WriteString(pPlayer->GetTitleString());
  350. PlayerPoo->WriteString(NULL);
  351. PlayerPoo->WriteString(NULL);
  352. PlayerPoo->WriteString(NULL);
  353. PlayerPoo->WriteDWORD(0x05001119);
  354. PlayerPoo->WriteDWORD(0x05001161);
  355. PlayerPoo->WriteDWORD(0x050011E3);
  356. PlayerPoo->WriteDWORD(0x04000EB6);//0x040002BD );
  357. PlayerPoo->WriteDWORD(0x04000EB6);//0x040002F2 );
  358. PlayerPoo->WriteDWORD(0x04000EB6);//0x040004A8 );
  359. }
  360. if (dwContents & 1) {
  361. PlayerPoo->WriteDWORD(0x1C0);
  362. }
  363. return PlayerPoo;
  364. }
  365. BinaryWriter *IdentifyObject(CPhysicsObj *pEntity)
  366. {
  367. enum AppraisalProfilePackHeader {
  368. Packed_None = 0,
  369. Packed_IntStats = (1 << 0),
  370. Packed_BoolStats = (1 << 1),
  371. Packed_FloatStats = (1 << 2),
  372. Packed_StringStats = (1 << 3),
  373. Packed_SpellList = (1 << 4), // 0x10
  374. Packed_WeaponProfile = (1 << 5),
  375. Packed_HookProfile = (1 << 6),
  376. Packed_ArmorProfile = (1 << 7),
  377. Packed_CreatureProfile = (1 << 8), // 0x100
  378. Packed_ArmorEnchant = (1 << 9),
  379. Packed_ResistEnchant = (1 << 10),
  380. Packed_WeaponEnchant = (1 << 11),
  381. Packed_DataIDStats = (1 << 12), // 0x1000
  382. Packed_Int64Stats = (1 << 13),
  383. Packed_ArmorLevels = (1 << 14)
  384. };
  385. BinaryWriter *IdentTotal = new BinaryWriter;
  386. BinaryWriter *IdentStuff = new BinaryWriter;
  387. //Possible sections
  388. IdentTotal->WriteDWORD(0xC9);
  389. IdentTotal->WriteDWORD(pEntity->m_dwGUID);
  390. BinaryWriter *Stuffing;
  391. DWORD dwSections = 0;
  392. /*
  393. if (Stuffing = IdentifyObject_DwordData(pEntity))
  394. {
  395. dwSections |= Packed_IntStats;
  396. IdentStuff->AppendData(Stuffing->GetData(), Stuffing->GetSize());
  397. delete Stuffing;
  398. }
  399. */
  400. dwSections |= Packed_IntStats;
  401. IdentStuff->WriteMap(pEntity->m_dwordProperties);
  402. dwSections |= Packed_Int64Stats;
  403. IdentStuff->WriteMap(pEntity->m_qwordProperties);
  404. dwSections |= Packed_BoolStats;
  405. IdentStuff->WriteMap(pEntity->m_boolProperties);
  406. dwSections |= Packed_FloatStats;
  407. IdentStuff->WriteMap(pEntity->m_floatProperties);
  408. if (Stuffing = IdentifyObject_StringData(pEntity))
  409. {
  410. dwSections |= Packed_StringStats;
  411. IdentStuff->AppendData(Stuffing->GetData(), Stuffing->GetSize());
  412. delete Stuffing;
  413. }
  414. /*
  415. dwSections |= Packed_StringStats;
  416. IdentStuff->WriteMap(pEntity->m_stringProperties);
  417. dwSections |= Packed_DataIDStats;
  418. IdentStuff->WriteMap(pEntity->m_dataIDProperties);
  419. if (Stuffing = IdentifyObject_PlayerData(pEntity))
  420. {
  421. dwSections |= Packed_CreatureProfile;
  422. IdentStuff->AppendData(Stuffing->GetData(), Stuffing->GetSize());
  423. delete Stuffing;
  424. }
  425. */
  426. IdentTotal->WriteDWORD(dwSections);
  427. IdentTotal->WriteDWORD(1); // Succeeded: always yes for now
  428. IdentTotal->AppendData(IdentStuff->GetData(), IdentStuff->GetSize());
  429. delete IdentStuff;
  430. return IdentTotal;
  431. }
  432. BinaryWriter *GetStatInfo(CBasePlayer *pPlayer)
  433. {
  434. //0x05, 0x14, 0x19, 0x1E, 0x62, 0x7D (we'll add unassigned / totalxp too)
  435. BinaryWriter Stats;
  436. Stats.WriteDWORD(eTotalBurden);
  437. Stats.WriteDWORD(pPlayer->GetObjectStat(eTotalBurden));
  438. Stats.WriteDWORD(eTotalPyreal);
  439. Stats.WriteDWORD(pPlayer->GetObjectStat(eTotalPyreal));
  440. Stats.WriteDWORD(eTotalXP);
  441. Stats.WriteDWORD(pPlayer->GetObjectStat(eTotalXP));
  442. Stats.WriteDWORD(eUnassignedXP);
  443. Stats.WriteDWORD(pPlayer->GetObjectStat(eUnassignedXP));
  444. Stats.WriteDWORD(eLevel);
  445. Stats.WriteDWORD(pPlayer->GetObjectStat(eLevel));
  446. Stats.WriteDWORD(eRank);
  447. Stats.WriteDWORD(pPlayer->GetObjectStat(eRank));
  448. Stats.WriteDWORD(eBirth);
  449. Stats.WriteDWORD(pPlayer->GetObjectStat(eBirth));
  450. Stats.WriteDWORD(eAge);
  451. Stats.WriteDWORD(pPlayer->GetObjectStat(eAge));
  452. Stats.WriteDWORD(eFrozen);
  453. Stats.WriteDWORD(pPlayer->GetObjectStat(eFrozen));
  454. Stats.WriteDWORD(eUnknown2);
  455. Stats.WriteDWORD(pPlayer->GetObjectStat(eUnknown2));
  456. BinaryWriter *StatInfo = new BinaryWriter;
  457. StatInfo->WriteWORD(0xA);
  458. StatInfo->WriteWORD(0x40);
  459. StatInfo->AppendData(Stats.GetData(), Stats.GetSize());
  460. return StatInfo;
  461. }
  462. void WriteSkillData(WORD index, SKILL* skill, BinaryWriter *pFood)
  463. {
  464. pFood->WriteWORD(index);
  465. pFood->Align();
  466. pFood->AppendData(&skill->data, sizeof(_SKILLDATA));
  467. }
  468. BinaryWriter *GetSkillInfo(CBasePlayer *pPlayer)
  469. {
  470. BinaryWriter Skills;
  471. WriteSkillData(eAxe, pPlayer->GetSkillData(eAxe), &Skills);
  472. WriteSkillData(eBow, pPlayer->GetSkillData(eBow), &Skills);
  473. WriteSkillData(eCrossbow, pPlayer->GetSkillData(eCrossbow), &Skills);
  474. WriteSkillData(eDagger, pPlayer->GetSkillData(eDagger), &Skills);
  475. WriteSkillData(eMace, pPlayer->GetSkillData(eMace), &Skills); //05
  476. WriteSkillData(eMeleeDefense, pPlayer->GetSkillData(eMeleeDefense), &Skills);
  477. WriteSkillData(eMissileDefense, pPlayer->GetSkillData(eMissileDefense), &Skills);
  478. WriteSkillData(eSpear, pPlayer->GetSkillData(eSpear), &Skills);
  479. WriteSkillData(eStaff, pPlayer->GetSkillData(eStaff), &Skills);
  480. WriteSkillData(eSword, pPlayer->GetSkillData(eSword), &Skills); //10
  481. WriteSkillData(eThrownWeapons, pPlayer->GetSkillData(eThrownWeapons), &Skills);
  482. WriteSkillData(eUnarmedCombat, pPlayer->GetSkillData(eUnarmedCombat), &Skills);
  483. WriteSkillData(eArcaneLore, pPlayer->GetSkillData(eArcaneLore), &Skills);
  484. WriteSkillData(eMagicDefense, pPlayer->GetSkillData(eMagicDefense), &Skills);
  485. WriteSkillData(eManaConversion, pPlayer->GetSkillData(eManaConversion), &Skills); //15
  486. WriteSkillData(eAppraiseItem, pPlayer->GetSkillData(eAppraiseItem), &Skills);
  487. WriteSkillData(eAssessPerson, pPlayer->GetSkillData(eAssessPerson), &Skills);
  488. WriteSkillData(eDeception, pPlayer->GetSkillData(eDeception), &Skills);
  489. WriteSkillData(eHealing, pPlayer->GetSkillData(eHealing), &Skills);
  490. WriteSkillData(eJump, pPlayer->GetSkillData(eJump), &Skills); //20
  491. WriteSkillData(eLockpick, pPlayer->GetSkillData(eLockpick), &Skills);
  492. WriteSkillData(eRun, pPlayer->GetSkillData(eRun), &Skills);
  493. WriteSkillData(eAssessCreature, pPlayer->GetSkillData(eAssessCreature), &Skills);
  494. WriteSkillData(eAppraiseWeapon, pPlayer->GetSkillData(eAppraiseWeapon), &Skills);
  495. WriteSkillData(eAppraiseArmor, pPlayer->GetSkillData(eAppraiseArmor), &Skills); //25
  496. WriteSkillData(eAppraiseMagicItem, pPlayer->GetSkillData(eAppraiseMagicItem), &Skills);
  497. WriteSkillData(eCreatureEnchantment, pPlayer->GetSkillData(eCreatureEnchantment), &Skills);
  498. WriteSkillData(eItemEnchantment, pPlayer->GetSkillData(eItemEnchantment), &Skills);
  499. WriteSkillData(eLifeMagic, pPlayer->GetSkillData(eLifeMagic), &Skills);
  500. WriteSkillData(eWarMagic, pPlayer->GetSkillData(eWarMagic), &Skills); //30
  501. WriteSkillData(eLeadership, pPlayer->GetSkillData(eLeadership), &Skills);
  502. WriteSkillData(eLoyalty, pPlayer->GetSkillData(eLoyalty), &Skills);
  503. WriteSkillData(eFletching, pPlayer->GetSkillData(eFletching), &Skills);
  504. WriteSkillData(eAlchemy, pPlayer->GetSkillData(eAlchemy), &Skills);
  505. WriteSkillData(eCooking, pPlayer->GetSkillData(eCooking), &Skills);
  506. BinaryWriter *SkillInfo = new BinaryWriter;
  507. SkillInfo->WriteWORD(0x23); //skillcount
  508. SkillInfo->WriteWORD(0x20);
  509. SkillInfo->AppendData(Skills.GetData(), Skills.GetSize());
  510. return SkillInfo;
  511. }
  512. BinaryWriter *LoginCharacter(CBasePlayer *pPlayer)
  513. {
  514. //Game Event 0x0013
  515. BinaryWriter *LC = new BinaryWriter;
  516. LC->WriteDWORD(0x0013);
  517. LC->WriteDWORD(0x001B); // section flags
  518. LC->WriteDWORD(0x000A);
  519. BinaryWriter *StatInfo = GetStatInfo(pPlayer);
  520. LC->AppendData(StatInfo->GetData(), StatInfo->GetSize());
  521. delete StatInfo;
  522. // BOOL properties
  523. LC->WriteWORD(5);
  524. LC->WriteWORD(0x20);
  525. LC->WriteDWORD(0x0004);
  526. LC->WriteDWORD(0x0000);
  527. LC->WriteDWORD(0x002C);
  528. LC->WriteDWORD(0x0001); // Is ADMIN
  529. LC->WriteDWORD(0x002D);
  530. LC->WriteDWORD(0x0000);
  531. LC->WriteDWORD(0x002E);
  532. LC->WriteDWORD(0x0000);
  533. LC->WriteDWORD(0x002F);
  534. LC->WriteDWORD(0x0000);
  535. // Character strings
  536. LC->WriteWORD(4);
  537. LC->WriteWORD(0x10);
  538. LC->WriteDWORD(0x0001);
  539. LC->WriteString(pPlayer->GetName());
  540. LC->WriteDWORD(0x0003);
  541. LC->WriteString(pPlayer->GetGenderString());
  542. LC->WriteDWORD(0x0004);
  543. LC->WriteString(pPlayer->GetRaceString());
  544. LC->WriteDWORD(0x0005);
  545. LC->WriteString(pPlayer->GetTitleString());
  546. //What the hell is this?
  547. LC->WriteWORD(1);
  548. LC->WriteWORD(0x20);
  549. LC->WriteDWORD(0x00000004);
  550. LC->WriteDWORD(0x30000000);
  551. LC->WriteDWORD(0x0103); //loginmask2
  552. LC->WriteDWORD(0x0001); //???
  553. LC->WriteDWORD(0x01FF);
  554. for (int i = 1; i <= 6; i++)
  555. {
  556. ATTRIBUTE* attrib = pPlayer->GetAttributeData((eAttribute)i);
  557. LC->WriteData(&attrib->data, sizeof(_ATTRIBUTEDATA));
  558. }
  559. for (int i = 1; i <= 5; i += 2)
  560. {
  561. VITAL* vital = pPlayer->GetVitalData((eVital)i);
  562. LC->WriteData(&vital->data, sizeof(_VITALDATA));
  563. }
  564. BinaryWriter *SkillInfo = GetSkillInfo(pPlayer);
  565. LC->AppendData(SkillInfo->GetData(), SkillInfo->GetSize());
  566. delete SkillInfo;
  567. //spellbook:
  568. //LC->WriteWORD( 55 );
  569. LC->WriteWORD(6); // Number of spells
  570. LC->WriteWORD(0x40); // Required ?
  571. LC->WriteDWORD(2366); //Spell ID
  572. LC->WriteFloat(2.0f); //Unknown
  573. for (int i = 0; i < 5; i++) //Add 6 starter spells
  574. {
  575. LC->WriteDWORD( i );
  576. LC->WriteFloat( 2.0f );
  577. }
  578. LC->WriteDWORD(0x0070); //loginmask3
  579. LC->WriteDWORD(0x11C4E56A);
  580. LC->WriteDWORD(0x00000000);//spellbar 1 count
  581. LC->WriteDWORD(0x00000000);//spellbar 2 count
  582. LC->WriteDWORD(0x00000000);//spellbar 3 count
  583. LC->WriteDWORD(0x00000000);//spellbar 4 count
  584. LC->WriteDWORD(0x00000000);//spellbar 5 count
  585. LC->WriteDWORD(0x00000000);//spellbar 6 count
  586. LC->WriteDWORD(0x00000000);//spellbar 7 count
  587. //LC->WriteDWORD(0x000007FF);//unknown..
  588. LC->WriteDWORD(0x00000041); //?unk20mask3
  589. LC->WriteDWORD(0x00000000); //?unk40mask3
  590. LC->WriteDWORD(0x00000000);//equipment
  591. LC->WriteDWORD(0x00000000);//inventory
  592. return LC;
  593. }
  594. BinaryWriter *HealthUpdate(CBaseMonster *pMonster)
  595. {
  596. MESSAGE_BEGIN(HealthUpdate);
  597. HealthUpdate->WriteDWORD(0x1C0);
  598. HealthUpdate->WriteDWORD(pMonster->m_dwGUID);
  599. HealthUpdate->WriteFloat(GetVitalPercent(pMonster->GetVitalData(eHealth), 0));
  600. MESSAGE_END(HealthUpdate);
  601. }
  602. BinaryWriter *InventoryEquip(DWORD dwItemID, DWORD dwCoverage)
  603. {
  604. MESSAGE_BEGIN(InventoryEquip);
  605. InventoryEquip->WriteDWORD(0x23);
  606. InventoryEquip->WriteDWORD(dwItemID);
  607. InventoryEquip->WriteDWORD(dwCoverage);
  608. MESSAGE_END(InventoryEquip);
  609. }
  610. BinaryWriter *InventoryMove(DWORD dwItemID, DWORD dwContainerID, DWORD dwSlot, DWORD dwType)
  611. {
  612. MESSAGE_BEGIN(InventoryMove);
  613. InventoryMove->WriteDWORD(0x22);
  614. InventoryMove->WriteDWORD(dwItemID);
  615. InventoryMove->WriteDWORD(dwContainerID);
  616. InventoryMove->WriteDWORD(dwSlot);
  617. InventoryMove->WriteDWORD(dwType);
  618. MESSAGE_END(InventoryMove);
  619. }
  620. BinaryWriter *InventoryDrop(DWORD dwItemID)
  621. {
  622. MESSAGE_BEGIN(InventoryDrop);
  623. InventoryDrop->WriteDWORD(0x19A);
  624. InventoryDrop->WriteDWORD(dwItemID);
  625. MESSAGE_END(InventoryDrop);
  626. }
  627. BinaryWriter *MoveUpdate(CPhysicsObj *pEntity)
  628. {
  629. MESSAGE_BEGIN(MoveUpdate);
  630. BinaryWriter *MovePayload = new BinaryWriter;
  631. MoveUpdate->WriteDWORD(0xF748);
  632. MoveUpdate->WriteDWORD(pEntity->m_dwGUID);
  633. //Nasty, but it reduces the linecount =) Sorry Akilla.
  634. DWORD dwPayloadFlags = 4;
  635. if (!pEntity->m_Angles.w) dwPayloadFlags |= 0x00000008;
  636. else MovePayload->WriteFloat(pEntity->m_Angles.w);
  637. if (!pEntity->m_Angles.x) dwPayloadFlags |= 0x00000010;
  638. else MovePayload->WriteFloat(pEntity->m_Angles.x);
  639. if (!pEntity->m_Angles.y) dwPayloadFlags |= 0x00000020;
  640. else MovePayload->WriteFloat(pEntity->m_Angles.y);
  641. if (!pEntity->m_Angles.z) dwPayloadFlags |= 0x00000040;
  642. else MovePayload->WriteFloat(pEntity->m_Angles.z);
  643. if (pEntity->CanPickup()) {
  644. dwPayloadFlags |= 0x00000002;
  645. MovePayload->WriteDWORD(0x000000065);
  646. }
  647. MoveUpdate->WriteDWORD(dwPayloadFlags);
  648. MoveUpdate->AppendData(pEntity->m_Origin);
  649. MoveUpdate->AppendData(MovePayload->GetData(), MovePayload->GetSize());
  650. MoveUpdate->WriteWORD(pEntity->m_wInstance);
  651. MoveUpdate->WriteWORD(pEntity->m_wNumMovements);
  652. MoveUpdate->WriteWORD(pEntity->m_wNumPortals);
  653. MoveUpdate->WriteWORD(0);
  654. delete MovePayload;
  655. MESSAGE_END(MoveUpdate);
  656. }