Clone of Bael'Zharon's Respite @ https://github.com/boardwalk/bzr

CreateObject.cpp 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /*
  2. * Bael'Zharon's Respite
  3. * Copyright (C) 2014 Daniel Skorupski
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along
  15. * with this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17. */
  18. #include "BinReader.h"
  19. #include "Core.h"
  20. #include "Log.h"
  21. #include "ObjectManager.h"
  22. #include "PhysicsDesc.h"
  23. #include "ResourceCache.h"
  24. #include "util.h"
  25. enum PublicWeenieDescFlags
  26. {
  27. kPluralName = 0x00000001,
  28. kItemsCapacity = 0x00000002,
  29. kContainersCapacity = 0x00000004,
  30. kValue = 0x00000008,
  31. kUseability = 0x00000010,
  32. kUseRadius = 0x00000020,
  33. kMonarch = 0x00000040,
  34. kUIEffects = 0x00000080,
  35. kAmmoType = 0x00000100,
  36. kCombatUse = 0x00000200,
  37. kStructure = 0x00000400,
  38. kMaxStructure = 0x00000800,
  39. kStackSize = 0x00001000,
  40. kMaxStackSize = 0x00002000,
  41. kContainerID = 0x00004000,
  42. kWielderID = 0x00008000,
  43. kValidLocations = 0x00010000,
  44. kLocation = 0x00020000,
  45. kPriority = 0x00040000,
  46. kTargetType = 0x00080000,
  47. kBlipColor = 0x00100000,
  48. kBurden = 0x00200000,
  49. kSpellID = 0x00400000,
  50. kRadarEnum = 0x00800000,
  51. kRadarDistance = 0x01000000,
  52. kHouseOwner = 0x02000000,
  53. kHouseRestrictions = 0x04000000,
  54. kPScript = 0x08000000,
  55. kHookType = 0x10000000,
  56. kHookItemTypes = 0x20000000,
  57. kIconOverlay = 0x40000000,
  58. kMaterialType = 0x80000000
  59. };
  60. enum BitfieldIndex
  61. {
  62. kOpenable = 0x0001,
  63. kInscribable = 0x0002,
  64. kStuck = 0x0004,
  65. kPlayer = 0x0008,
  66. kAttackable = 0x0010,
  67. kPlayerKiller = 0x0020,
  68. kHiddenAdmin = 0x0040,
  69. kUIHidden = 0x0080,
  70. kBook = 0x0100,
  71. kVendor = 0x0200,
  72. kPkswitch = 0x0400,
  73. kNpkswitch = 0x0800,
  74. kDoor = 0x1000,
  75. kCorpse = 0x2000,
  76. kLifestone = 0x4000,
  77. kFood = 0x8000,
  78. kHealer = 0x00010000,
  79. kLockpick = 0x00020000,
  80. kPortal = 0x00040000,
  81. kAdmin = 0x00100000,
  82. kFreePkstatus = 0x00200000,
  83. kImmuneCellRestrictions = 0x00400000,
  84. kRequiresPackslot = 0x00800000,
  85. kRetained = 0x01000000,
  86. kPklitePkstatus = 0x02000000,
  87. kIncludesSecondHeader = 0x04000000,
  88. kBindstone = 0x08000000,
  89. kVolatileRare = 0x10000000,
  90. kWieldOnUse = 0x20000000,
  91. kWieldLeft = 0x40000000
  92. };
  93. enum PublicWeenieDescFlags2
  94. {
  95. kIconUnderlay = 0x0001,
  96. kCooldownID = 0x0002,
  97. kCooldownDuration = 0x0004,
  98. kPetOwner = 0x0008
  99. };
  100. // AC: ObjDesc
  101. static void handleObjDesc(BinReader& reader, Object&)
  102. {
  103. uint8_t eleven = reader.readByte();
  104. assert(eleven == 0x11);
  105. UNUSED(eleven);
  106. uint8_t paletteCount = reader.readByte();
  107. uint8_t textureCount = reader.readByte();
  108. uint8_t modelCount = reader.readByte();
  109. if(paletteCount != 0)
  110. {
  111. /*palette*/ reader.readPackedInt();
  112. }
  113. for(uint8_t i = 0; i < paletteCount; i++)
  114. {
  115. /*palette*/ reader.readPackedInt();
  116. /*offset*/ reader.readByte();
  117. /*length*/ reader.readByte();
  118. }
  119. for(uint8_t i = 0; i < textureCount; i++)
  120. {
  121. /*index*/ reader.readByte();
  122. /*old*/ reader.readPackedInt();
  123. /*new*/ reader.readPackedInt();
  124. }
  125. for(uint8_t i = 0; i < modelCount; i++)
  126. {
  127. /*index*/ reader.readByte();
  128. /*model*/ reader.readPackedInt();
  129. }
  130. reader.align();
  131. }
  132. // AC: PublicWeenieDesc
  133. static void handleWeenieDesc(BinReader& reader, Object& object)
  134. {
  135. uint32_t flags = reader.readInt();
  136. uint32_t flags2 = 0;
  137. object.setProperty(StringProperty::kName, reader.readString());
  138. /*weenieClassId*/ reader.readPackedInt();
  139. object.setProperty(DIDProperty::kIcon, reader.readPackedInt());
  140. object.setProperty(IntProperty::kItemType, reader.readInt()); // ITEM_TYPE enum, prefixed with TYPE_
  141. uint32_t bitfield = reader.readInt(); // PublicWeenieDesc::BitfieldIndex enum, prefixed with BF_
  142. reader.align();
  143. if(bitfield & kInscribable)
  144. {
  145. object.setProperty(BoolProperty::kInscribable, true);
  146. }
  147. if(bitfield & kStuck)
  148. {
  149. object.setProperty(BoolProperty::kStuck, true);
  150. }
  151. if(bitfield & kAttackable)
  152. {
  153. object.setProperty(BoolProperty::kAttackable, true);
  154. }
  155. if(bitfield & kHiddenAdmin)
  156. {
  157. object.setProperty(BoolProperty::kHiddenAdmin, true);
  158. }
  159. if(bitfield & kUIHidden)
  160. {
  161. object.setProperty(BoolProperty::kUIHidden, true);
  162. }
  163. if(bitfield & kAdmin)
  164. {
  165. object.setProperty(BoolProperty::kIsAdmin, true);
  166. }
  167. if(bitfield & kRequiresPackslot)
  168. {
  169. object.setProperty(BoolProperty::kRequiresBackpackSlot, true);
  170. }
  171. if(bitfield & kRetained)
  172. {
  173. object.setProperty(BoolProperty::kRetained, true);
  174. }
  175. if(bitfield & kWieldOnUse)
  176. {
  177. object.setProperty(BoolProperty::kWieldOnUse, true);
  178. }
  179. if(bitfield & kIncludesSecondHeader)
  180. {
  181. flags2 = reader.readInt();
  182. }
  183. if(flags & kPluralName)
  184. {
  185. object.setProperty(StringProperty::kPluralName, reader.readString());
  186. }
  187. if(flags & kItemsCapacity)
  188. {
  189. object.setProperty(IntProperty::kItemsCapacity, reader.readByte());
  190. }
  191. if(flags & kContainersCapacity)
  192. {
  193. object.setProperty(IntProperty::kContainersCapacity, reader.readByte());
  194. }
  195. if(flags & kAmmoType)
  196. {
  197. object.setProperty(IntProperty::kAmmoType, reader.readShort());
  198. }
  199. if(flags & kValue)
  200. {
  201. object.setProperty(IntProperty::kValue, reader.readInt());
  202. }
  203. if(flags & kUseability)
  204. {
  205. object.setProperty(IntProperty::kItemUseable, reader.readInt());
  206. }
  207. if(flags & kUseRadius)
  208. {
  209. object.setProperty(FloatProperty::kUseRadius, reader.readFloat());
  210. }
  211. if(flags & kTargetType)
  212. {
  213. object.setProperty(IntProperty::kTargetType, reader.readInt());
  214. }
  215. if(flags & kUIEffects)
  216. {
  217. object.setProperty(IntProperty::kUIEffects, reader.readInt());
  218. }
  219. if(flags & kCombatUse)
  220. {
  221. object.setProperty(IntProperty::kCombatUse, reader.readByte());
  222. }
  223. if(flags & kStructure)
  224. {
  225. object.setProperty(IntProperty::kStructure, reader.readShort());
  226. }
  227. if(flags & kMaxStructure)
  228. {
  229. object.setProperty(IntProperty::kMaxStructure, reader.readShort());
  230. }
  231. if(flags & kStackSize)
  232. {
  233. object.setProperty(IntProperty::kStackSize, reader.readShort());
  234. }
  235. if(flags & kMaxStackSize)
  236. {
  237. object.setProperty(IntProperty::kMaxStackSize, reader.readShort());
  238. }
  239. if(flags & kContainerID)
  240. {
  241. object.setProperty(IIDProperty::kContainer, reader.readInt());
  242. }
  243. if(flags & kWielderID)
  244. {
  245. object.setProperty(IIDProperty::kWielder, reader.readInt());
  246. }
  247. if(flags & kValidLocations)
  248. {
  249. object.setProperty(IntProperty::kLocations, reader.readInt());
  250. }
  251. if(flags & kLocation)
  252. {
  253. object.setProperty(IntProperty::kCurrentWieldedLocation, reader.readInt());
  254. }
  255. if(flags & kPriority)
  256. {
  257. object.setProperty(IntProperty::kClothingPriority, reader.readInt());
  258. }
  259. if(flags & kBlipColor)
  260. {
  261. object.setProperty(IntProperty::kRadarblipColor, reader.readByte());
  262. }
  263. if(flags & kRadarEnum)
  264. {
  265. object.setProperty(IntProperty::kShowableOnRadar, reader.readByte());
  266. }
  267. if(flags & kPScript)
  268. {
  269. object.setProperty(DIDProperty::kPhysicsScript, reader.readPackedInt());
  270. }
  271. if(flags & kRadarDistance)
  272. {
  273. object.setProperty(FloatProperty::kObviousRadarRange, reader.readFloat());
  274. }
  275. if(flags & kBurden)
  276. {
  277. object.setProperty(IntProperty::kEncumbVal, reader.readShort());
  278. }
  279. if(flags & kSpellID)
  280. {
  281. object.setProperty(DIDProperty::kSpell, reader.readShort()); // A short?
  282. }
  283. if(flags & kHouseOwner)
  284. {
  285. object.setProperty(IIDProperty::kHouseOwner, reader.readInt());
  286. }
  287. if(flags & kHouseRestrictions)
  288. {
  289. /*flags*/ reader.readInt();
  290. /*open*/ reader.readInt();
  291. /*allegiance*/ reader.readInt();
  292. uint16_t guestCount = reader.readShort();
  293. /*guestLimit*/ reader.readShort();
  294. for(uint16_t i = 0; i < guestCount; i++)
  295. {
  296. /*guest*/ reader.readInt();
  297. /*storage*/ reader.readInt();
  298. }
  299. }
  300. if(flags & kHookItemTypes)
  301. {
  302. object.setProperty(IntProperty::kHookPlacement, reader.readShort());
  303. object.setProperty(IntProperty::kHookItemType, reader.readShort());
  304. }
  305. if(flags & kMonarch)
  306. {
  307. object.setProperty(IIDProperty::kMonarch, reader.readInt());
  308. }
  309. if(flags & kHookType)
  310. {
  311. object.setProperty(IntProperty::kHookType, reader.readShort());
  312. }
  313. if(flags & kIconOverlay)
  314. {
  315. object.setProperty(DIDProperty::kIconOverlay, reader.readPackedInt());
  316. }
  317. if(flags2 & kIconUnderlay)
  318. {
  319. object.setProperty(DIDProperty::kIconUnderlay, reader.readPackedInt());
  320. }
  321. if(flags & kMaterialType)
  322. {
  323. object.setProperty(IntProperty::kMaterialType, reader.readInt());
  324. }
  325. // properties beyond here are a guess
  326. if(flags2 & kCooldownID)
  327. {
  328. object.setProperty(IntProperty::kSharedCooldown, reader.readInt());
  329. }
  330. if(flags2 & kCooldownDuration)
  331. {
  332. object.setProperty(FloatProperty::kCooldownDuration, reader.readDouble());
  333. }
  334. if(flags2 & kPetOwner)
  335. {
  336. object.setProperty(IIDProperty::kPetOwner, reader.readInt());
  337. }
  338. reader.align();
  339. assert(reader.remaining() == 0);
  340. }
  341. void handleCreateObject(BinReader& reader)
  342. {
  343. ObjectId objectId = ObjectId{reader.readInt()};
  344. Object& object = Core::get().objectManager()[objectId];
  345. handleObjDesc(reader, object);
  346. PhysicsDesc physicsDesc;
  347. read(reader, physicsDesc);
  348. handleWeenieDesc(reader, object);
  349. }