Clone of UAS2 @ https://github.com/drudgedance/uas2

cCovenantCrystal.cpp 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. /*
  2. * This file is part of UAS2.
  3. *
  4. * UAS2 is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * UAS2 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. * You should have received a copy of the GNU General Public License
  14. * along with UASv1; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. */
  17. /**
  18. * @file cCovenantCrystal.cpp
  19. * Implements functionality for covenant crystals.
  20. *
  21. * This class is referenced whenever a covenant crystal is created, used, or assessed.
  22. * Inherits from the cObject class.
  23. */
  24. //#include "Client.h"
  25. #include "MasterServer.h"
  26. #include "Object.h"
  27. #include "WorldManager.h"
  28. /***************
  29. * constructors
  30. **************/
  31. /**
  32. * Handles the creation of covenant crystals.
  33. *
  34. * Called whenever a covenant crystal object should be initialized.
  35. */
  36. cCovenant::cCovenant( WORD type, DWORD dwGUID, DWORD dwHouseID, char *szName, char *szDescription, cLocation *pcLoc )
  37. {
  38. SetLocation( pcLoc );
  39. m_dwGUID = dwGUID;
  40. m_dwHouseID = dwHouseID;
  41. m_strName.assign( szName );
  42. m_strDescription.assign( szDescription );
  43. m_dwModel = type;
  44. m_fStatic = TRUE;
  45. }
  46. /**********
  47. * methods
  48. *********/
  49. /**
  50. * Handles the message sent for the creation of covenant crystals in the world.
  51. *
  52. * This function is called whenever a covenant crystal should be created in the world for a client.
  53. *
  54. * @return cMessage - Returns a Create Object (0x0000F745) server message.
  55. */
  56. cMessage cCovenant::CreatePacket()
  57. {
  58. cMessage cmCreate;
  59. char szCommand[200];
  60. RETCODE retcode;
  61. char OwnerIDBuff[9];
  62. DWORD OwnerID = NULL;
  63. char szName[75];
  64. std::string strName = m_strName;
  65. sprintf( szCommand, "SELECT OwnerID FROM houses_covenants WHERE HouseID = %d;",m_dwHouseID);
  66. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  67. retcode = SQLExecute( cDatabase::m_hStmt );
  68. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_CHAR, OwnerIDBuff, sizeof( OwnerIDBuff ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  69. if (SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS) {
  70. sscanf(OwnerIDBuff,"%08x",&OwnerID);
  71. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  72. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  73. sprintf( szCommand, "SELECT Name FROM avatar WHERE AvatarGUID = %08x;",OwnerID);
  74. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  75. retcode = SQLExecute( cDatabase::m_hStmt );
  76. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_CHAR, szName, sizeof( szName ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  77. // Return SQL_SUCCESS if there is a player that corresponds to owner of the fetched covenant crystal
  78. if (SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS) {
  79. std::string str1 = szName;
  80. strName.assign(str1 + "'s " + m_strName);
  81. }
  82. }
  83. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  84. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  85. float flpScale; // Scale used in Packet being Sent
  86. float flmScale = 0; // Model Data Scale
  87. DWORD dwFlags1 = 0x00018003; // Flags1
  88. if (WORD(m_wModel) != 0x3CF8) { // if not apartment (cottages, villas, mansions)
  89. flmScale = 1.2f;
  90. dwFlags1 += 0x00000080L; // mask 'floatscale' if cottage, villa, or mansion
  91. }
  92. /*
  93. AnimConfig
  94. 0x00B8L cottages,villas,mansions
  95. 0x00EAL apartment
  96. dwModel
  97. 0x0AAFL cottages,villas,mansions
  98. 0x0C7AL apartment
  99. wModelID
  100. 0x2DC2 mansion
  101. 0x2ECC villa
  102. 0x2DC5 villa
  103. 0x5173 cottage
  104. 0x3CF8 apartment
  105. wIconID
  106. 0x218C
  107. */
  108. cmCreate << 0xF745L
  109. << m_dwGUID
  110. << BYTE( 0x11 )
  111. << BYTE( 0 )
  112. << BYTE( 0 )
  113. << BYTE( 0 );
  114. cmCreate << dwFlags1;
  115. cmCreate << 0x00000414; // Type of portal (0x0410 = solid; 0x0414 = not solid?)
  116. // Flags1 Mask: 0x00018003 or 0x00018083
  117. {
  118. // Flags1 & 0x00100000 -- Unknown Count
  119. DWORD dwUnkCount = 0x0000000C;
  120. BYTE ownedByte;
  121. if (OwnerID) {
  122. ownedByte = 0x0B;
  123. } else {
  124. ownedByte = 0x0A;
  125. }
  126. BYTE unknownByte[0x0C] = { 0x00,0x00,0x3D,0x00,0x02,0x00,0x00,0x00,
  127. ownedByte, // model appearance: owned = 0x0B; unowned = 0x0A, 0x0C?
  128. 0x00,0x00,0x00};
  129. cmCreate << dwUnkCount;
  130. for ( int i = 0; i < dwUnkCount; ++i ) {
  131. cmCreate << unknownByte[i];
  132. }
  133. DWORD dwUnknownDword = 0x0L;
  134. cmCreate << dwUnknownDword;
  135. // Flags1 & 0x00008000 -- Location
  136. cmCreate.pasteData( (UCHAR*)&m_Location, sizeof(m_Location) ); // the location
  137. //Flags1 & 0x0000002 -- DWORD ResourceID Animations
  138. DWORD dwAnimC = 0x09000000L + m_wAnimConfig;
  139. cmCreate << dwAnimC;
  140. // Flags1 & 0x00000001 -- DWORD dwModel = 0x02000001; // the model.
  141. DWORD dwModel = 0x02000000L + m_dwModel;
  142. cmCreate << dwModel;
  143. if (WORD(m_wModel) != 0x3CF8)
  144. {
  145. //Flags1 & 0x00000080 -- unknown_green
  146. if (flmScale > 0)
  147. {
  148. flpScale = flmScale; // FLOAT flpScale
  149. }
  150. else
  151. {
  152. flpScale = 1.0;
  153. }
  154. cmCreate << flpScale;
  155. }
  156. }
  157. // SeaGreens
  158. WORD wUnkFlag2 = 0x0004;
  159. WORD wUnkFlag3 = 0x0000;
  160. WORD wUnkFlag4 = 0x0000;
  161. WORD wUnkFlag6 = 0x0004; // always seems same as wUnkFlag2
  162. WORD wUnkFlag7 = 0x0000;
  163. WORD wUnkFlag8 = 0x0000;
  164. WORD wUnkFlag10 = 0x0000;
  165. cmCreate << m_wPositionSequence // movement 0x0001
  166. << wUnkFlag2 // animations
  167. << wUnkFlag3 // bubble modes
  168. << wUnkFlag4 // num jumps
  169. << m_wNumPortals
  170. << wUnkFlag6 // anim count
  171. << wUnkFlag7 // overrides
  172. << wUnkFlag8
  173. << WORD(0x0D7F) // m_wNumLogins // 0x0D4B
  174. << wUnkFlag10;
  175. DWORD dwFlags2 = 0x0030L; // Flags2 -- Defines what data comes next
  176. if (m_dwOwnerID) {
  177. dwFlags2 += 0x02000000L; // mask 'houseOwnerID' if owned
  178. }
  179. cmCreate << dwFlags2;
  180. cmCreate << strName.c_str(); // Object's Name
  181. cmCreate << WORD(m_wModel) << WORD(m_wIcon);
  182. DWORD dwObjectFlags1 = 0x00000000; // 0x0080 -- Miscellaneous Object
  183. DWORD dwObjectFlags2 = 0x00001014; // 0x0004 -- Cannot be picked up; 0x0010 -- Can be selected
  184. cmCreate << dwObjectFlags1 << dwObjectFlags2;
  185. // Flags2 & 0x00000010
  186. DWORD dwunknown_v2 = 0x00000020; // Value
  187. cmCreate << dwunknown_v2;
  188. // Flags2 & 0x00000020
  189. float flApproach = 3.0f;
  190. cmCreate << flApproach;
  191. if (OwnerID) {
  192. // Flags2 & 0x02000000
  193. cmCreate << OwnerID;
  194. }
  195. return cmCreate;
  196. }
  197. /**
  198. * Handles the actions of covenant crystal objects.
  199. *
  200. * This function is called whenever a covenant crystal is used or should perform an action.
  201. */
  202. void cCovenant::Action(cClient* who)
  203. {
  204. cMessage cmUseCrystal;
  205. char szCommand[200];
  206. RETCODE retcode;
  207. char OwnerIDBuff[9];
  208. DWORD OwnerID = NULL;
  209. char HouseGUIDBuff[9];
  210. DWORD HouseGUID = NULL;
  211. char szName[75];
  212. std::string strPlayerName = "";
  213. sprintf( szCommand, "SELECT OwnerID,GUID FROM houses WHERE wModel = %d;",m_dwHouseID);
  214. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  215. retcode = SQLExecute( cDatabase::m_hStmt );
  216. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_CHAR, OwnerIDBuff, sizeof( OwnerIDBuff ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  217. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_CHAR, HouseGUIDBuff, sizeof( HouseGUIDBuff ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  218. // Return SQL_SUCCESS if there is a house that corresponds to the covenant crystal
  219. if (SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS) {
  220. sscanf(OwnerIDBuff,"%08x",&OwnerID);
  221. sscanf(HouseGUIDBuff,"%08x",&HouseGUID);
  222. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  223. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  224. sprintf( szCommand, "SELECT Name FROM avatar WHERE AvatarGUID = %08x;",OwnerID);
  225. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  226. retcode = SQLExecute( cDatabase::m_hStmt );
  227. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_CHAR, szName, sizeof( szName ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  228. // Return SQL_SUCCESS if there is a player that corresponds to owner of the fetched house
  229. if (SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS) {
  230. std::string str1 = szName;
  231. strPlayerName.assign(str1);
  232. }
  233. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  234. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  235. } else {
  236. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  237. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  238. }
  239. cmUseCrystal<< 0xF74CL // Packet type
  240. << who->m_pcAvatar->GetGUID() // Character's GUID
  241. << m_wNumLogins // number of logins
  242. << ++m_wPositionSequence // sequence number
  243. << ++m_wNumAnims // Number Animations this login session
  244. << WORD(0x00) // Activity
  245. << WORD(0x06)
  246. << WORD(0x3D) // Starting Stance
  247. << m_dwGUID; // Covenant Crystals's GUID
  248. cmUseCrystal.pasteData( (UCHAR*)&m_Location, sizeof(m_Location) ); // Covenant Crystals' location
  249. cmUseCrystal<< 0x19C5EE4F // bitfield?
  250. << 0x40400000 // float1 -- unknown float
  251. << 0x00000000 // float2 -- unknown float
  252. << 0x7F7FFFFF // unknown3 -- unknown DWORD
  253. << 0x3F800000 // speed (1)
  254. << 0x41700000 // float4 -- unknown float
  255. << 0x00000000 // heading
  256. << 0x3F800000; // unknown -- unknown DWORD
  257. cWorldManager::SendToAllInFocus( who->m_pcAvatar->m_Location, cmUseCrystal, 3 );
  258. // eLeM: Display Dwelling Purchase/Maintenance Panel
  259. int i;
  260. cMessage cmDisplayPanel;
  261. cmDisplayPanel << 0xF7B0L << who->m_pcAvatar->GetGUID( ) << ++who->m_dwF7B0Sequence << 0x021DL
  262. << m_dwGUID; // Covenant Crystal's GUID
  263. DWORD ownerType = 0x00000001; // Self = 0x00000001; Allegiance = 0x00000003
  264. DWORD levelReq = 0x00000001; // Apartment, Cottage = 0x00000014; Villa = 0x00000023; Mansion = 0x00000032
  265. DWORD unknown2 = 0xFFFFFFFF;
  266. DWORD rankReq = 0xFFFFFFFF; // Apartment, Cottage, Villa = 0xFFFFFFFF; Mansion = 0x00000006
  267. DWORD unknown3 = 0xFFFFFFFF;
  268. DWORD unknown4 = 0x00000000;
  269. DWORD unknown5 = 0x00000001;
  270. DWORD ownerName= 0x00000000;
  271. DWORD purchaseCount = 0x00000001; // Apartment = 2; Cottage, Villa = 3; Mansion = 6;
  272. cmDisplayPanel << HouseGUID // Dwelling ID
  273. << OwnerID // Dwelling Owner ID (NULL == 0x00000000)
  274. << ownerType
  275. << levelReq // level requirement to purchase this dwelling (-1 if no requirement)
  276. << unknown2
  277. << rankReq // rank requirement to purchase this dwelling (-1 if no requirement)
  278. << unknown3
  279. << unknown4
  280. // << unknown5
  281. << strPlayerName.c_str(); // name of the current owner (NULL == 0x00000000)
  282. /* Item type:
  283. 0x00000111 = Pyreal
  284. 0x00002DBE = Writ of Refuge / Writs of Refuge
  285. 0x00001086 = Mattekar Hide Sleeves
  286. 0x00000E74 = Gold Phyntos Wasp Wing
  287. 0x00002527 = Golden Gromnie
  288. 0x000021FD = A Lucky Gold Letter
  289. 0x000024C5 = Dread Mattekar Paw
  290. */
  291. DWORD dwPurchaseCount; // Apartment = 2; Cottage, Villa = 3; Mansion = 6;
  292. sprintf( szCommand, "SELECT COUNT(ID) FROM houses_purchase WHERE HouseID = %d;",m_dwHouseID );
  293. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  294. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  295. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwPurchaseCount, sizeof( dwPurchaseCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  296. retcode = SQLFetch( cDatabase::m_hStmt );
  297. if( retcode == SQL_NO_DATA )
  298. dwPurchaseCount = 0;
  299. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  300. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  301. cmDisplayPanel << dwPurchaseCount; // the number of items required to purchase this dwelling
  302. /* Item type:
  303. 0x00000111 = Pyreal
  304. 0x00002DBE = Writ of Refuge / Writs of Refuge
  305. 0x00001086 = Mattekar Hide Sleeves
  306. 0x00000E74 = Gold Phyntos Wasp Wing
  307. 0x00002527 = Golden Gromnie
  308. 0x000021FD = A Lucky Gold Letter
  309. 0x000024C5 = Dread Mattekar Paw
  310. */
  311. /* Purchase Amount:
  312. Apartment:
  313. 0x000186A0 100,000 Pyreal
  314. 0x00000001 1 Writ of Refuge
  315. Cottage:
  316. 0x000493E0 300,000 Pyreal
  317. 0x00000001 1 Writ of Refuge
  318. Other Item:
  319. 0x00000001 1 Mattekar Hide Sleeves
  320. Villa:
  321. 0x001E8480 2,000,000 Pyreal
  322. 0x00000005 5 Writs of Refuge
  323. Other Item:
  324. 0x00000001 1 Gold Phyntos Wasp Wing
  325. Mansion:
  326. 0x00989680 10,000,000 Pyreal
  327. 0x00000014 20 Writs of Refuge
  328. Other Items:
  329. 0x00000014 20 Golden Gromnie
  330. 0x0000000F 15 A Lucky Gold Letter
  331. 0x00000002 2 Dread Mattekar Paw
  332. */
  333. DWORD dwBuyType;
  334. DWORD dwBuyRequired;
  335. DWORD dwBuyPaid;
  336. // String buyName;
  337. // String buyPluralName;
  338. sprintf( szCommand, "SELECT ItemLinker,Required,Paid FROM houses_purchase WHERE HouseID = %d;",m_dwHouseID );
  339. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  340. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  341. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwBuyType, sizeof( dwBuyType ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  342. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwBuyRequired, sizeof( dwBuyRequired ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  343. retcode = SQLBindCol( cDatabase::m_hStmt, 3, SQL_C_ULONG, &dwBuyPaid, sizeof( dwBuyPaid ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  344. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i ) {
  345. if( retcode == SQL_NO_DATA ) {
  346. dwBuyRequired = 1;
  347. dwBuyPaid = 0;
  348. dwBuyType = 12;
  349. }
  350. cItemModels *pcModel = cItemModels::FindModel(dwBuyType);
  351. std::string strPluralName = pcModel->m_strName.c_str();
  352. strPluralName.assign(strPluralName + "s");
  353. cmDisplayPanel << dwBuyRequired // quantity required
  354. << dwBuyPaid // quantity paid
  355. << DWORD(pcModel->m_wModel) // item's object type
  356. << pcModel->m_strName.c_str() // name of this item
  357. << strPluralName.c_str(); // plural name of this item (if not specified, use <name> followed by 's' or 'es')
  358. }
  359. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  360. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  361. DWORD dwMaintenanceCount; // Apartment, Cottage = 1; Villa, Mansion = 2;
  362. sprintf( szCommand, "SELECT COUNT(ID) FROM houses_maintenance WHERE HouseID = %d;",m_dwHouseID );
  363. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  364. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  365. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwMaintenanceCount, sizeof( dwMaintenanceCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  366. retcode = SQLFetch( cDatabase::m_hStmt );
  367. if( retcode == SQL_NO_DATA )
  368. dwMaintenanceCount = 0;
  369. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  370. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  371. cmDisplayPanel << dwMaintenanceCount; // the number of items required to pay the maintenance cost for this dwelling
  372. /* Maintenance Amount:
  373. Apartment:
  374. 0x00002710 10,000 Pyreal
  375. Cottage:
  376. 0x00007530 30,000 Pyreal
  377. Villa:
  378. 0x000186A0 100,000 Pyreal
  379. 0x00000002 2 Writs of Refuge
  380. Mansion:
  381. 0x000F4240 1,000,000 Pyreal
  382. 0x00000010 10 Writs of Refuge
  383. */
  384. DWORD dwMaintainType;
  385. DWORD dwMaintainRequired;
  386. DWORD dwMaintainPaid;
  387. // String maintainName;
  388. // String maintainPluralName;
  389. sprintf( szCommand, "SELECT ItemLinker,Required,Paid FROM houses_maintenance WHERE HouseID = %d;",m_dwHouseID );
  390. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  391. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  392. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwMaintainType, sizeof( dwMaintainType ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  393. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwMaintainRequired, sizeof( dwMaintainRequired ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  394. retcode = SQLBindCol( cDatabase::m_hStmt, 3, SQL_C_ULONG, &dwMaintainPaid, sizeof( dwMaintainPaid ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  395. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i ) {
  396. if( retcode == SQL_NO_DATA ) {
  397. dwMaintainRequired = 1;
  398. dwMaintainPaid = 0;
  399. dwMaintainType = 12;
  400. }
  401. cItemModels *pcModel = cItemModels::FindModel(dwMaintainType);
  402. std::string strPluralName = pcModel->m_strName.c_str();
  403. strPluralName.assign(strPluralName + "s");
  404. cmDisplayPanel << dwMaintainRequired // quantity required
  405. << dwMaintainPaid // quantity paid
  406. << DWORD(pcModel->m_wModel) // item's object type
  407. << pcModel->m_strName.c_str() // name of this item
  408. << strPluralName.c_str(); // plural name of this item (if not specified, use <name> followed by 's' or 'es')
  409. }
  410. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  411. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  412. who->AddPacket(WORLD_SERVER,cmDisplayPanel,4);
  413. cMessage cmActionComplete;
  414. cmActionComplete << 0xF7B0L << who->m_pcAvatar->GetGUID( ) << ++who->m_dwF7B0Sequence << 0x01C7L << 0L;
  415. who->AddPacket(WORLD_SERVER,cmActionComplete,4);
  416. }
  417. /**
  418. * Handles the assessment of covenant crystal objects.
  419. *
  420. * This function is called whenever a covenant crystal is assessed by a client.
  421. *
  422. * Returns a Game Event (0x0000F7B0) server message of type Identify Object (0x000000C9).
  423. */
  424. void cCovenant::Assess(cClient *pcAssesser)
  425. {
  426. // eLeM: Covenant Crystal assess
  427. // cObject *pcObject = cWorldManager::FindObject( m_dwGUID );
  428. cMessage cmAssess;
  429. DWORD flags = 0x00000008;
  430. m_strDescription.assign(m_dwMode ? "The current maintenance has not been paid." : "The current maintenance has been paid.");
  431. WORD length = (m_dwMode ? 0x002B : 0x0027);
  432. cmAssess << 0xF7B0L << pcAssesser->m_pcAvatar->GetGUID() << ++pcAssesser->m_dwF7B0Sequence << 0xC9L << m_dwGUID
  433. << flags
  434. << 0x01L // Success = 0x01, Failure = 0x00
  435. << WORD(0x0001) // Total number of DWORDS
  436. << WORD(0x0008) // Unknown
  437. << 0x10L
  438. << this->m_strDescription.c_str();
  439. pcAssesser->AddPacket(WORLD_SERVER,cmAssess,4);
  440. cMessage cmActionComplete;
  441. cmActionComplete << 0xF7B0L << pcAssesser->m_pcAvatar->GetGUID( ) << ++pcAssesser->m_dwF7B0Sequence << 0x01C7L << 0L;
  442. pcAssesser->AddPacket(WORLD_SERVER,cmActionComplete,4);
  443. }