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

WorldServer.cpp 177KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065
  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 WorldServer.cpp
  19. * Processes client messages according to their pre-defined types.
  20. */
  21. //NOTES: This file has been extensively modified from the original version.
  22. // All of the known client (outbound) messages have been added to this code.
  23. #include "Client.h"
  24. #include "DatFile.h"
  25. #include "MasterServer.h"
  26. #include "RecvPacket.h"
  27. #include "WorldManager.h"
  28. #include "WorldServer.h"
  29. #include "Job.h"
  30. #include "cSpell.h"
  31. // ** F7B1: xxxx **
  32. #define ATTACK 0x0008
  33. #define MISSILE_ATTACK 0x000A
  34. #define TEXT_FROM_CLIENT 0x0015
  35. #define INVENTORY_ADD_ADJUST 0x0019
  36. #define INVENTORY_EQUIP 0x001A
  37. #define INVENTORY_DROP 0x001B
  38. #define SWEAR_ALLEGIANCE 0x001D
  39. #define BREAK_ALLEGIANCE 0x001E
  40. #define ALLEGIANCE_PANEL 0x001F
  41. #define SEND_TELL_GUID 0x0032 // Not sure about this one.
  42. #define TARGET_USE 0x0035 // Targeted Use (healing kits, etc); possibly used in trade skills as well.
  43. #define USE 0x0036 // Normal Use
  44. #define RAISE_VITAL 0x0044
  45. #define RAISE_ATTRIBUTE 0x0045
  46. #define RAISE_SKILL 0x0046
  47. #define TRAIN_SKILL 0x0047
  48. #define CAST_SPELL_NO_TARGET 0x0048
  49. #define CAST_SPELL_TARGET 0x004A
  50. #define CHANGE_COMBAT_MODE 0x0053
  51. #define STACK_ITEMS 0x0054
  52. #define SPLIT_ITEMS 0x0055
  53. #define SQUELCH 0x0058
  54. #define SQUELCH_ACCOUNT 0x0059
  55. #define SEND_TELL_NAME 0x005D
  56. #define VENDOR_BUY_ITEMS 0x005F // Buy Item(s) from Vendor
  57. #define VENDOR_SELL_ITEMS 0x0060 // Sell Item(s) to Vendor
  58. #define LIFESTONE_RECALL 0x0063
  59. #define CHARACTER_SPAWN 0x00A1
  60. #define CREATE_FELLOWSHIP 0x00A2
  61. #define DISBAND_FELLOWSHIP 0x00A3
  62. #define DISMISS_FELLOW_MEMBER 0x00A4
  63. #define RECRUIT_FELLOW_MEMBER 0x00A5
  64. #define FELLOWSHIP_PANEL 0x00A6
  65. #define WRITE_BOOK 0x00AB // Writing to a blank page in a book.
  66. #define UNK 0x00AC
  67. #define READ_BOOK 0x00AE
  68. #define INSCRIBE 0x00BF // Inscribe Item
  69. #define ASSESS 0x00C8 // Appraise and Assess
  70. #define GIVE_ITEM 0x00CD // Give Item (NPC)
  71. #define REMOVE_PRIVS 0x00D3 // Strip Access Level? May be useful.
  72. #define TELE_TO_LB 0x00D6 // Admin command?
  73. #define REPORT_ABUSE 0x0140
  74. #define SEND_TELL_MASK 0x0147
  75. #define CLOSE_CONTAINER_FORCED 0x0195 // Occurs automatically when you wander too far from a chest
  76. #define MAKE_SHORTCUT 0x019C
  77. #define REMOVE_SHORTCUT 0x019D
  78. #define ADJUST_SETTINGS 0x01A1
  79. #define SAVE_LIFESTONE_POS 0x01A2 // (@save)
  80. #define DELETE_SPELL_SHORTCUT 0x01A8
  81. #define STOP_ATTACK 0x01B7
  82. #define REQUEST_HEALTH_UPDATE 0x01BF
  83. #define RETRIEVE_AGE 0x01C2
  84. #define RETRIEVE_BIRTH 0x01C4
  85. #define EMOTE_TEXT 0x01DF
  86. #define EMOTE_COMMAND_TEXT 0x01E1
  87. #define ADD_SPELL_SHORTCUT 0x01E3
  88. #define REMOVE_SPELL_SHORTCUT 0x01E4
  89. #define TELEPORT_TO_PLAYER 0x01E6 //Admin command? (@teleto)
  90. #define PING_SERVER 0x01E9
  91. #define BEGIN_TRADE 0x01F6
  92. #define END_TRADE 0x01F7
  93. #define ADD_ITEM_TO_TRADE 0x01F8
  94. #define ACCEPT_TRADE 0x01FA
  95. #define WITHDRAW_OFFER 0x01FB
  96. #define CLEAR_TRADE_WINDOW 0x0204
  97. #define CONSENT_CLEAR 0x0216
  98. #define CONSENT_LIST 0x0217
  99. #define CONSENT_REMOVE 0x0218
  100. #define PERMIT_ADD 0x0219
  101. #define PERMIT_REMOVE 0x021A
  102. #define HOUSE_BUY 0x021C
  103. #define HOUSE_MAINTAIN 0x0221
  104. #define HOUSE_ABANDON 0x021F
  105. #define HOUSE_BOOT_NAME 0x024A // Boot by Name
  106. #define HOUSE_BOOT_ALL 0x025F // Boot Everyone
  107. #define HOUSE_GUEST_ADD 0x0245
  108. #define HOUSE_GUEST_REM_NAME 0x0246 // Remove Guest by Name
  109. #define HOUSE_OPEN_CLOSE 0x0247 // Open or Close
  110. #define HOUSE_STORAGE 0x0249 // Add or Remove by Name
  111. #define HOUSE_BOOT_NAME 0x024A // Boot by Name
  112. #define HOUSE_STORE_REM_ALL 0x024C // Remove All from Storage
  113. #define HOUSE_GUEST_LIST 0x024D
  114. #define SET_SPEAKER 0x0251
  115. #define SHOW_SPEAKER 0x0252
  116. #define CLEAR_SPEAKER 0x0253
  117. #define SET_MOTD 0x0254
  118. #define SHOW_MOTD 0x0255
  119. #define CLEAR_MOTD 0x0256
  120. #define HOUSE_GUEST_REM_ALL 0x025E // Remove all Guests from list
  121. #define HOUSE_BOOT_ALL 0x025F // Boot Everyone
  122. #define HOUSE_RECALL 0x0262
  123. #define GET_OBJECT_MANA 0x0263 // Buggy...
  124. #define HOUSE_HOOKS 0x0266 // On or Off
  125. #define HOUSE_GUEST_ALLEG 0x0267 // Add or Remove
  126. #define JOIN_CHESS_GAME 0x0269
  127. #define LEAVE_CHESS_GAME 0x026A
  128. #define MOVE_CHESS_PIECE 0x026B
  129. #define OFFER_CHESS_DRAW 0x026E
  130. #define HOUSE_AVAIL 0x0270
  131. #define ANSWER_POPUP 0x0275 // Answers a Yes/No pop-up question.
  132. #define ALLEG_BOOT 0x0277 // Boot Member by Name
  133. #define ALLEG_RECALL 0x0278 // Includes Mansion Recall
  134. #define SUICIDE 0x0279 // (@die)
  135. #define ALLEG_INFO 0x027B // Retrieve Info by Name
  136. #define MARKETPLACE_RECALL 0x028D
  137. #define PKLITE 0x028F // (@pklite)
  138. #define PROMOTE_FELLOW_LEADER 0x0290
  139. #define OPEN_CLOSE_FELLOWSHIP 0x0291
  140. #define JUMP 0xF61B
  141. #define MOVEMENT_LOW_PRIORITY 0xF61C // Animations
  142. #define MOVEMENT_HIGH_PRIORITY 0xF753 // Position Update
  143. // ** F7B0: xxxx **
  144. #define RECIEVE_MELEE_DAMAGE 0x01B2
  145. #define SET_PACK_CONTENTS 0x0196 // Add items to pack/chest/etc
  146. //Cubem0j0: Found this one by accident, sent after you buy something:
  147. //This is a sequenced message, after seq number comes 0x5F, GUID of the vendor,
  148. //then seems to always be 0x00000001, then the amount purchased (DWORD), then
  149. //lastly the GUID of the item.
  150. // ** Skill defines ** /
  151. #define AXE 0x00000001
  152. #define BOW 0x00000002
  153. #define CROSSBOW 0x00000003
  154. #define DAGGER 0x00000004
  155. #define MACE 0x00000005
  156. #define MELEE_DEFENSE 0x00000006
  157. #define MISSILE_DEFENSE 0x00000007
  158. #define SPEAR 0x00000009
  159. #define STAFF 0x0000000A
  160. #define SWORD 0x0000000B
  161. #define THROWN_WEAPONS 0x0000000C
  162. #define UNARMED_COMBAT 0x0000000D
  163. #define ARCANE_LORE 0x0000000E
  164. #define MAGIC_DEFENSE 0x0000000F
  165. #define MANA_CONVERSION 0x00000010
  166. #define ITEM_TINKERING 0x00000012
  167. #define ASSESS_PERSON 0x00000013
  168. #define DECEPTION 0x00000014
  169. #define HEALING 0x00000015
  170. #define S_JUMP 0x00000016
  171. #define LOCKPICK 0x00000017
  172. #define RUN 0x00000018
  173. #define ASSESS_CREATURE 0x0000001B
  174. #define WEAPON_TINKERING 0x0000001C
  175. #define ARMOR_TINKERING 0x0000001D
  176. #define MAGIC_ITEM_TINKERING 0x0000001E
  177. #define CREATURE_ENCHANTMENT 0x0000001F
  178. #define ITEM_ENCHANTMENT 0x00000020
  179. #define LIFE_MAGIC 0x00000021
  180. #define WAR_MAGIC 0x00000022
  181. #define LEADERSHIP 0x00000023
  182. #define LOYALTY 0x00000024
  183. #define FLETCHING 0x00000025
  184. #define ALCHEMY 0x00000026
  185. #define COOKING 0x00000027
  186. #define SALVAGING 0x00000028
  187. cWeapon *pcW;
  188. cShield *pcS;
  189. cAmmo *pcMW;
  190. //Initialize static members
  191. //============================================
  192. DWORD cWorldServer::m_dwSendCRCSeed;
  193. DWORD cWorldServer::m_dwRecvCRCSeed;
  194. WORD cWorldServer::m_wLogicalID;
  195. SOCKET cWorldServer::m_Socket;
  196. float intRange;
  197. DWORD NPCID;
  198. DWORD CORPSEID;
  199. //============================================
  200. /**
  201. * Processes World Server packets
  202. *
  203. * This function is called when the client sends a general World Server message.
  204. * These encompass the actions performed by a client's avatar.
  205. */
  206. void cClient::ProcessPacket_WS( cRecvPacket* pcRecvPacket )
  207. {
  208. m_dwLastRecvTime = timeGetTime( );
  209. switch ( pcRecvPacket->GetFlags( ) )
  210. {
  211. //Client request for the resending of packet(s)
  212. case 0x00000002:
  213. {
  214. #ifdef _DEBUG
  215. cMasterServer::ServerMessage( ColorGreen, this, "Incorrect server-to-client message detected." );
  216. #endif
  217. DWORD dwNumLost;
  218. WORD wTime;
  219. wTime = pcRecvPacket->GetTime( );
  220. pcRecvPacket->CopyPayload( 0, &dwNumLost, 4 ); //the number of packets lost
  221. DWORD *dwLost = new DWORD[dwNumLost]; //DWORD array dwNumLost created to hold lost packets
  222. pcRecvPacket->CopyPayload( 4, dwLost, dwNumLost * 4 ); //the lost packets (of count dwNumLost)
  223. m_PacketPipe_WS.ProcessLostPackets( dwNumLost, dwLost, m_saSockAddr ); //process the lost packets
  224. SAFEDELETE_ARRAY( dwLost )
  225. return;
  226. }
  227. //Client confirmation that the previous packet sequence was received
  228. case 0x00000004:
  229. {
  230. DWORD dwLastGoodSeq;
  231. m_PacketPipe_WS.m_wTime = pcRecvPacket->GetTime( );
  232. pcRecvPacket->CopyPayload( 0, &dwLastGoodSeq, 4 );
  233. m_PacketPipe_WS.ClearSentPackets( dwLastGoodSeq );
  234. return ;
  235. }
  236. case 0x00100000:
  237. case 0x00200200: //Cube: This flag appears to be sent whenever movement updates occur (F753 / F61C)
  238. case 0x00000200:
  239. {
  240. m_PacketPipe_WS.m_dwRecvSequence = pcRecvPacket->GetSequence( );
  241. m_PacketPipe_WS.m_wTime = pcRecvPacket->GetTime( );
  242. if ( pcRecvPacket->GetFlags( ) == 0x00100000 )
  243. {
  244. m_PacketPipe_WS.ReturnPing( m_saSockAddr );
  245. m_pcAvatar->m_dwPingCount++;
  246. /* Process delayed or periodic actions */
  247. //Lifestone Recall
  248. if ((m_pcAvatar->m_dwPingCount > 7) && (m_pcAvatar->m_wLifeStone == 1))
  249. {
  250. AddPacket( WORLD_SERVER, m_pcAvatar->LifestoneRecall(), 3 );
  251. if(m_pcAvatar->m_LSLoc.m_dwLandBlock > 0x0000FFFF)
  252. {
  253. cWorldManager::MoveAvatar( this, m_pcAvatar->m_LSLoc, 1 );
  254. }
  255. m_pcAvatar->m_dwPingCount = 0;
  256. m_pcAvatar->m_wLifeStone = 0;
  257. }
  258. //Marketplace Recall
  259. else if((m_pcAvatar->m_dwPingCount > 7) && (m_pcAvatar->m_wMarketplace == 1))
  260. {
  261. AddPacket( WORLD_SERVER, m_pcAvatar->MarketplaceRecall(), 3 );
  262. cWorldManager::MoveAvatar( this,cMasterServer::m_MarketLoc, 1 );
  263. m_pcAvatar->m_dwPingCount = 0;
  264. m_pcAvatar->m_wMarketplace = 0;
  265. }
  266. //House Recall
  267. else if((m_pcAvatar->m_dwPingCount > 7) && (m_pcAvatar->m_wHouseRecall == 1))
  268. {
  269. AddPacket( WORLD_SERVER, m_pcAvatar->HouseRecall(), 3 );
  270. if(m_pcAvatar->m_HRLoc.m_dwLandBlock > 0x0000FFFF)
  271. {
  272. cWorldManager::MoveAvatar( this, m_pcAvatar->m_HRLoc, 1 );
  273. }
  274. m_pcAvatar->m_dwPingCount = 0;
  275. m_pcAvatar->m_wHouseRecall = 0;
  276. }
  277. //PK Lite
  278. else if ((m_pcAvatar->m_dwPingCount > 7) && (m_pcAvatar->m_wPKlite == 1))
  279. {
  280. cMasterServer::PKLite( this, true );
  281. m_pcAvatar->m_dwPingCount = 0;
  282. m_pcAvatar->m_wPKlite = 0;
  283. }
  284. //Health regeneration
  285. if( m_pcAvatar->m_cStats.m_lpcVitals[0].m_dwCurrent > m_pcAvatar->m_cStats.m_lpcVitals[0].m_lTrueCurrent )
  286. {
  287. AddPacket( WORLD_SERVER, m_pcAvatar->SetHealth(m_pcAvatar->m_cStats.m_lpcVitals[0].m_lTrueCurrent + 1), 4 );
  288. }
  289. //Stamina regeneration
  290. if( m_pcAvatar->m_cStats.m_lpcVitals[1].m_dwCurrent > m_pcAvatar->m_cStats.m_lpcVitals[1].m_lTrueCurrent )
  291. {
  292. AddPacket( WORLD_SERVER, m_pcAvatar->SetStamina(m_pcAvatar->m_cStats.m_lpcVitals[1].m_lTrueCurrent + 1), 4 );
  293. }
  294. //Mana regeneration
  295. if( m_pcAvatar->m_cStats.m_lpcVitals[2].m_dwCurrent > m_pcAvatar->m_cStats.m_lpcVitals[2].m_lTrueCurrent )
  296. {
  297. AddPacket( WORLD_SERVER, m_pcAvatar->SetMana(m_pcAvatar->m_cStats.m_lpcVitals[2].m_lTrueCurrent + 1), 4 );
  298. }
  299. //Update database record of avatar location
  300. m_pcAvatar->UpdateAvatarLocation();
  301. return;
  302. }
  303. break; //case 0x00100000, case 0x00200200, and case 0x00000200
  304. }
  305. }
  306. switch ( m_bWorldState )
  307. {
  308. case 0: //First login
  309. {
  310. if ( pcRecvPacket->GetFlags( ) == 0x00080000 )
  311. {
  312. m_bWorldState = 2;
  313. char szIP[32];
  314. cMasterServer::FormatIP_Port( m_saSockAddr, szIP );
  315. SendPacket100( );
  316. }
  317. break;
  318. }
  319. case 1: //Subsequent logins
  320. {
  321. if ( pcRecvPacket->GetFlags( ) == 0x00080000 )
  322. {
  323. m_bWorldState = 2;
  324. m_PacketPipe_WS.Reset( );
  325. SendPacket100( );
  326. }
  327. break;
  328. }
  329. case 2:
  330. {
  331. if ( pcRecvPacket->GetFlags( ) == 0x100 ) //100 message acknowledged
  332. {
  333. m_bWorldState = 3;
  334. SendPacket400( );
  335. }
  336. break;
  337. }
  338. case 3:
  339. {
  340. if ( pcRecvPacket->GetFlags( ) == 0x400 ) //400 message acknowledged
  341. {
  342. m_bWorldState = 4;
  343. cMasterServer::CreateInventory( this ); //Send create packets for inventory contents
  344. cMasterServer::SendLoginData( this ); //Send login data (uses CreateInventory information)
  345. m_pcAvatar->m_wLifeStone = 0;
  346. //Display console text information for a World Server connection
  347. char szIP[32];
  348. cMasterServer::FormatIP_Port( m_saSockAddr, szIP );
  349. UpdateConsole( " World Server connection:\r\n"
  350. " User: %s\r\n"
  351. " Avatar: %s\r\n"
  352. " IP: %s\r\n", this->m_szAccountName, m_pcAvatar->m_strName.c_str(), szIP);
  353. }
  354. break;
  355. }
  356. case 4: //General World Packet
  357. {
  358. cFragmentHeader FH;
  359. DWORD MType1, MType2, MType3, MType4;
  360. BYTE *pbData;
  361. MType1 = 0x0L;
  362. MType2 = 0x0L;
  363. MType3 = 0x0L; //Cubem0j0: for part 1 of F7B1:0045, 0046, 0047 messages
  364. MType4 = 0x0L; //Cubem0j0: for part 2 of F7B1:0045, 0046, 0047 messages
  365. if ( pcRecvPacket->GetFlags( ) & 0x00000200 )
  366. {
  367. if ( pcRecvPacket->GetFlags( ) == 0x00200200 )
  368. {
  369. pbData = (BYTE *)&(*pcRecvPacket)[sizeof( cTransportHeader ) + 6];
  370. }
  371. else if ( pcRecvPacket->GetFlags( ) == 0x00000200 || pcRecvPacket->GetFlags( ) == 0x00000201 )
  372. {
  373. pbData = pcRecvPacket->GetPayloadFront( );
  374. }
  375. while ( pbData < pcRecvPacket->GetPayloadBack( ) )
  376. {
  377. CopyMemory( &FH, pbData, sizeof( cFragmentHeader ) );
  378. pbData += sizeof( cFragmentHeader );
  379. CopyMemory( &MType1, pbData, 4 );
  380. CopyMemory( &MType2, &pbData[8], 4 );
  381. CopyMemory( &MType3, &pbData[12], 4 );
  382. CopyMemory( &MType4, &pbData[16], 4);
  383. switch ( MType1 )
  384. {
  385. case 0xF653:
  386. { //Exit world
  387. m_bWorldState = 5;
  388. break;
  389. }
  390. case 0xF7A9:
  391. { //Client needs landblock
  392. cMasterServer::ServerMessage( ColorGreen,this, "!telemap to another location or try typing /render radius 5." );
  393. #ifdef _DEBUG
  394. UpdateConsole( " Landblock data needed. \r\n" );
  395. #endif // _DEBUG
  396. //ServerMessage(UserParsing, "* You don't have at least one of the landblocks in your new area. !telemap to another location or try typing /render radius 5.", COLOR_RED);
  397. break;
  398. }
  399. case 0xF6EA:
  400. {
  401. //Object no longer exsists
  402. break;
  403. }
  404. case 0xF7B1:
  405. {
  406. switch ( MType2 )
  407. {
  408. /*
  409. Attack Types
  410. Melee: ATTACK: 0x0008
  411. Missile: MISSILE_ATTACK: 0x000A
  412. Magic: CAST_SPELL_TARGET: 0x004A
  413. */
  414. //The client performs a melee attack
  415. case ATTACK: //0x0008
  416. {
  417. //Attack target GUID
  418. DWORD dwTargetGUID = *( DWORD * )&pbData[12];
  419. //Search the client list by GUID for the attack target
  420. cClient* pcTargetObj = cClient::FindClient( dwTargetGUID );
  421. //If no client is found (in which case the target is NOT another player)
  422. if( !pcTargetObj )
  423. {
  424. cObject* pcTargetObj = cWorldManager::FindObject( dwTargetGUID );
  425. intRange = m_pcAvatar->GetRange( m_pcAvatar->m_Location.m_dwLandBlock,m_pcAvatar->m_Location.m_flX,m_pcAvatar->m_Location.m_flY,m_pcAvatar->m_Location.m_flZ, pcTargetObj->m_Location.m_dwLandBlock, pcTargetObj->m_Location.m_flX, pcTargetObj->m_Location.m_flY, pcTargetObj->m_Location.m_flZ );
  426. //If beyond attack range
  427. if(intRange > pcTargetObj->m_fApproachDistance)
  428. {
  429. //cMessage Anim = m_pcAvatar->RunToAnimation( m_pcAvatar->m_dwGUID, pcTargetObj->GetGUID());
  430. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, m_pcAvatar->RunToAnimation( m_pcAvatar->m_dwGUID, pcTargetObj->GetGUID()), 3 );
  431. cMasterServer::ServerMessage(ColorGreen,this,"%s is too far away to attack.",pcTargetObj->m_strName.c_str());
  432. break;
  433. }
  434. //If not beyond attack range
  435. else if (intRange <= pcTargetObj->m_fApproachDistance)
  436. {
  437. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, m_pcAvatar->RunToAnimation( m_pcAvatar->m_dwGUID, pcTargetObj->GetGUID()), 2 );
  438. cMessage Anim = m_pcAvatar->RunToAnimation( m_pcAvatar->m_dwGUID, pcTargetObj->GetGUID());
  439. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, Anim, 2 );
  440. /*
  441. DWORD dwDamageType = 0x04;
  442. if (m_pcAvatar->myWeapon)
  443. dwDamageType = m_pcAvatar->myWeapon->m_dwDamageType;
  444. */
  445. float flDamageSlider = *( float * )&pbData[20];
  446. if(( pcTargetObj->m_dwObjectFlags1 & 0x00000010 )&&(pcTargetObj->m_fDeadOrAlive == true))
  447. {
  448. pcTargetObj->Attack( this , flDamageSlider, ++m_dwF7B0Sequence);
  449. SimpleAI::SetUnderAttack( dwTargetGUID, m_pcAvatar->GetGUID() );
  450. }
  451. AddPacket( WORLD_SERVER, m_pcAvatar->AttackCompleteMessage( ++m_dwF7B0Sequence ), 4 );
  452. }
  453. break;
  454. }
  455. //If a client is found (in which case the target is another player)
  456. #ifdef _DEBUG
  457. char szMessage[155];
  458. sprintf( szMessage, " PK: %f %f",pcTargetObj->m_pcAvatar->m_fIsPK,m_pcAvatar->m_fIsPK );
  459. UpdateConsole((char *)szMessage);
  460. #endif
  461. if( ( pcTargetObj->m_pcAvatar->m_fIsPK == 0) && ( m_pcAvatar->m_fIsPK == 0 ) )
  462. break;
  463. //Find the distance to the target
  464. intRange = m_pcAvatar->GetRange( m_pcAvatar->m_Location.m_dwLandBlock,m_pcAvatar->m_Location.m_flX,m_pcAvatar->m_Location.m_flY,m_pcAvatar->m_Location.m_flZ, pcTargetObj->m_pcAvatar->m_Location.m_dwLandBlock, pcTargetObj->m_pcAvatar->m_Location.m_flX, pcTargetObj->m_pcAvatar->m_Location.m_flY, pcTargetObj->m_pcAvatar->m_Location.m_flZ );
  465. //If the target is out of range
  466. if (intRange > 10)
  467. {
  468. cMasterServer::ServerMessage(ColorGreen,this,"The target is out of range. :(");
  469. //cMessage cmCompleteAttackMessage = m_pcAvatar->AttackCompleteMessage( ++m_dwF7B0Sequence );
  470. AddPacket( WORLD_SERVER, m_pcAvatar->AttackCompleteMessage( ++m_dwF7B0Sequence ), 4 );
  471. break;
  472. }
  473. else if (intRange > 3)
  474. {
  475. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, m_pcAvatar->Animation( 0x07L, 2.0f ), 3 );
  476. AddPacket( WORLD_SERVER, m_pcAvatar->AttackCompleteMessage( ++m_dwF7B0Sequence ), 4 );
  477. break;
  478. }
  479. else if (intRange > 1)
  480. {
  481. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, m_pcAvatar->RunToAnimation( m_pcAvatar->m_dwGUID, pcTargetObj->m_pcAvatar->GetGUID()), 2 );
  482. break;
  483. }
  484. DWORD dwDamageType = 0x04;
  485. if (m_pcAvatar->myWeapon->m_fEquipped == 1)
  486. dwDamageType = m_pcAvatar->myWeapon->m_dwDamageType;
  487. float flDamageSlider = *( float * )&pbData[20];
  488. //Take a swing
  489. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, m_pcAvatar->CombatAnimation( pcTargetObj->m_pcAvatar->GetGUID() ), 3 );
  490. WORD wTotalOpponentHealth = pcTargetObj->m_pcAvatar->GetTotalHealth();
  491. //Now perform a very basic combat calculation..no where near accurate.
  492. DWORD dwDamage = m_pcAvatar->CalculateDamage( NULL, flDamageSlider, 0.0f );
  493. double dSeverity = ( double ) wTotalOpponentHealth / dwDamage;
  494. int iNewHealth;
  495. BOOL fKilledPlayer = FALSE;
  496. //Following variable(s) only used if there is a kill
  497. cMessage cmAnim;
  498. cMessage cmBeginMessage = m_pcAvatar->AttackBeginMessage( ++m_dwF7B0Sequence, m_pcAvatar->GetGUID( ) );
  499. cMessage cmHealthLoss = pcTargetObj->m_pcAvatar->DecrementHealth( dwDamage, iNewHealth );
  500. //If the attacked player is killed
  501. if( iNewHealth <= 0 )
  502. {
  503. fKilledPlayer = TRUE;
  504. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, pcTargetObj->m_pcAvatar->ChangeCombatMode( FALSE, 0 ), 3 );
  505. cWorldManager::SendToAllInFocus( pcTargetObj->m_pcAvatar->m_Location, pcTargetObj->m_pcAvatar->Animation( 0x11L, 2.0f ), 3 );
  506. cMasterServer::Corpse( pcTargetObj );
  507. cWorldManager::SendToAllInFocus( pcTargetObj->m_pcAvatar->m_Location, pcTargetObj->m_pcAvatar->ChangeCombatMode( FALSE, 0), 3 );
  508. cWorldManager::TeleportAvatar( pcTargetObj, cMasterServer::m_StartingLoc );
  509. char szDeathNotice[200];
  510. wsprintf( szDeathNotice, "%s has killed %s", m_pcAvatar->m_strName.c_str(), pcTargetObj->m_pcAvatar->m_strName.c_str( ) );
  511. pcTargetObj->AddPacket( WORLD_SERVER, pcTargetObj->m_pcAvatar->SetHealth( pcTargetObj->m_pcAvatar->GetTotalHealth( ) ), 4 );
  512. }
  513. //If the attacked player is not killed
  514. else
  515. {
  516. AddPacket(WORLD_SERVER,m_pcAvatar->CombatAnimation( dwTargetGUID ),4);
  517. pcTargetObj->AddPacket( WORLD_SERVER, pcTargetObj->m_pcAvatar->RecieveDamageMessage( ++pcTargetObj->m_dwF7B0Sequence, m_pcAvatar->m_strName, dwDamageType, dSeverity, dwDamage, 0x7 ), 4 );
  518. AddPacket( WORLD_SERVER, m_pcAvatar->DoDamageMessage( ++m_dwF7B0Sequence, pcTargetObj->m_pcAvatar->m_strName, dwDamageType, dSeverity, dwDamage), 4 );
  519. }
  520. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, m_pcAvatar->CombatAnimation( dwTargetGUID ), 3 );
  521. AddPacket( WORLD_SERVER, m_pcAvatar->AttackBeginMessage( ++m_dwF7B0Sequence, m_pcAvatar->GetGUID( ) ), 4 );
  522. pcTargetObj->AddPacket( WORLD_SERVER, pcTargetObj->m_pcAvatar->DecrementHealth( dwDamage, iNewHealth ), 4 );
  523. AddPacket( WORLD_SERVER, m_pcAvatar->AttackCompleteMessage( ++m_dwF7B0Sequence ), 4 );
  524. break;
  525. }
  526. //The client performs a missile attack
  527. case MISSILE_ATTACK: //0x000A
  528. {
  529. break;
  530. }
  531. //Local chat
  532. case TEXT_FROM_CLIENT: //0x0015
  533. {
  534. WORD wTextLength = FH.m_wFragmentLength - 14 - sizeof( cFragmentHeader );
  535. if ( wTextLength > 0 )
  536. {
  537. char *szMessageText = new char[wTextLength+1];
  538. CopyMemory( szMessageText, &pbData[14], wTextLength );
  539. szMessageText[wTextLength] = '\0';
  540. cMasterServer::ParseCommand( szMessageText, wTextLength, this );
  541. SAFEDELETE_ARRAY( szMessageText )
  542. }
  543. break; //case 0x0015
  544. }
  545. //Picking up or unequipping an object
  546. case INVENTORY_ADD_ADJUST: //0x0019
  547. {
  548. DWORD dwObjectGUID = *( DWORD * )&pbData[12];
  549. if ( !dwObjectGUID )
  550. break;
  551. DWORD dwDestination = *( DWORD * )&pbData[20];
  552. //Search for the object in the avatar's inventory
  553. cObject *pcObj = m_pcAvatar->FindInventory( dwObjectGUID );
  554. //If the object was found in the avatar's inventory
  555. if( pcObj ) //Move object into inventory
  556. {
  557. if( pcObj->m_fEquipped != 0 ) //If the object was equipped
  558. {
  559. //Insert Inventory Item
  560. cMessage cmInsertInventoryItem;
  561. cmInsertInventoryItem << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x22L << dwObjectGUID << m_pcAvatar->GetGUID( ) << dwDestination << 0L;
  562. AddPacket( WORLD_SERVER, cmInsertInventoryItem, 4 );
  563. unsigned char ucSound[16] = {
  564. 0x50, 0xF7, 0x00, 0x00, 0xD6, 0xFD, 0x09, 0x50, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F,
  565. };
  566. CopyMemory( &ucSound[4], &m_pcAvatar->m_dwGUID, 4 );
  567. cMessage cmSound;
  568. cmSound.CannedData( ucSound, 16 );
  569. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmSound, 3 );
  570. cMessage cWrChange;
  571. //Change Model
  572. WORD wModelChangeType = m_pcAvatar->m_wNumLogins;
  573. pcObj->m_fEquipped = 0;
  574. char szCommand[255];
  575. RETCODE retcode;
  576. sprintf( szCommand, "UPDATE items_instance_inventory SET Equipped = %d WHERE GUID = %lu AND OwnerGUID = %lu;",pcObj->m_fEquipped,dwObjectGUID,m_pcAvatar->GetGUID() );
  577. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  578. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  579. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_CLOSE ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  580. int paletteChange = m_pcAvatar->m_bBasicPaletteChange;
  581. int textureChange = m_pcAvatar->m_bBasicTextureChange;
  582. //Loop through the palettes and textures of previously equipped items
  583. for ( iterObject_lst itObject = m_pcAvatar->m_lstInventory.begin( ); itObject != m_pcAvatar->m_lstInventory.end( ); ++itObject )
  584. {
  585. if ( ( *itObject )->m_fEquipped == 2 )
  586. {
  587. cItemModels *pcItemInv = cItemModels::FindModel(( *itObject )->GetItemModelID());
  588. if ( ( *itObject )->m_bWearPaletteChange != 0)
  589. paletteChange += ( *itObject )->m_bWearPaletteChange;
  590. if ( pcItemInv->m_bWearTextureChange != 0)
  591. textureChange += pcItemInv->m_bWearTextureChange;
  592. }
  593. }
  594. cWrChange << DWORD(0xF625)
  595. << DWORD(m_pcAvatar->m_dwGUID)
  596. << BYTE(0x11) // 11 Vector Palettes
  597. << BYTE(paletteChange)
  598. << BYTE(textureChange)
  599. << BYTE(m_pcAvatar->m_bBasicModelChange);
  600. cWrChange << WORD(0x007E);
  601. //Loop through the avatar's default palettes
  602. if ( m_pcAvatar->m_bBasicPaletteChange != 0)
  603. {
  604. for (int i = 0; i < m_pcAvatar->m_bBasicPaletteChange; i++)
  605. {
  606. cWrChange.pasteData((UCHAR*)&m_pcAvatar->m_BasicVectorPal[i],sizeof(m_pcAvatar->m_BasicVectorPal[i]));
  607. //cWrChange.pasteData((UCHAR*)&m_pcAvatar->pc,sizeof(m_pcAvatar->pc));
  608. }
  609. }
  610. //Loop through the palettes of previously equipped items
  611. for ( itObject = m_pcAvatar->m_lstInventory.begin( ); itObject != m_pcAvatar->m_lstInventory.end( ); ++itObject )
  612. {
  613. if ( ( *itObject )->m_fEquipped == 2 )
  614. {
  615. cItemModels *pcItemInv = cItemModels::FindModel(( *itObject )->GetItemModelID());
  616. if ( ( *itObject )->m_bWearPaletteChange != 0)
  617. {
  618. for (int i = 0; i < ( *itObject )->m_bWearPaletteChange; i++)
  619. {
  620. cWrChange.pasteData((UCHAR*)&( *itObject )->m_WearVectorPal[i],sizeof(( *itObject )->m_WearVectorPal[i]));
  621. }
  622. }
  623. }
  624. }
  625. //Loop through the avatar's default textures
  626. if ( m_pcAvatar->m_bBasicTextureChange != 0)
  627. {
  628. for (int i = 0; i < m_pcAvatar->m_bBasicTextureChange; i++)
  629. {
  630. cWrChange.pasteData((UCHAR*)&m_pcAvatar->m_BasicVectorTex[i],sizeof(m_pcAvatar->m_BasicVectorTex[i]));
  631. //cWrChange.pasteData((UCHAR*)&m_pcAvatar->pc,sizeof(m_pcAvatar->pc));
  632. }
  633. }
  634. //Loop through the textures of previously equipped items
  635. for ( itObject = m_pcAvatar->m_lstInventory.begin( ); itObject != m_pcAvatar->m_lstInventory.end( ); ++itObject )
  636. {
  637. if ( ( *itObject )->m_fEquipped == 2 )
  638. {
  639. cItemModels *pcItemInv = cItemModels::FindModel(( *itObject )->GetItemModelID());
  640. if ( pcItemInv->m_bWearTextureChange != 0)
  641. {
  642. for (int i = 0; i < pcItemInv->m_bWearTextureChange; i++)
  643. {
  644. cWrChange.pasteData((UCHAR*)&pcItemInv->m_WearVectorTex[i],sizeof(pcItemInv->m_WearVectorTex[i]));
  645. }
  646. }
  647. }
  648. }
  649. bool modelIsCovered;
  650. if ( m_pcAvatar->m_bBasicModelChange != 0)
  651. {
  652. //Loop through the avatar's default models
  653. //Do not include avatar models superceded by item models
  654. for (int i = 0; i < m_pcAvatar->m_bBasicModelChange; i++)
  655. {
  656. modelIsCovered = false;
  657. //Loop through the models of previously equipped items
  658. for ( itObject = m_pcAvatar->m_lstInventory.begin( ); itObject != m_pcAvatar->m_lstInventory.end( ); ++itObject )
  659. {
  660. if ( ( *itObject )->m_fEquipped == 2 )
  661. {
  662. cItemModels *pcItemInv = cItemModels::FindModel(( *itObject )->GetItemModelID());
  663. if ( pcItemInv->m_bWearModelChange != 0)
  664. {
  665. for (int j = 0; j < pcItemInv->m_bWearModelChange; j++)
  666. {
  667. //Find whether the item affects the given avatar body part
  668. //If so, the item model index will equal the given avatar model index
  669. if(m_pcAvatar->m_BasicVectorMod[i].m_bModelIndex == pcItemInv->m_WearVectorMod[j].m_bModelIndex)
  670. {
  671. modelIsCovered = true;
  672. }
  673. }
  674. }
  675. }
  676. }
  677. if (!modelIsCovered)
  678. cWrChange.pasteData((UCHAR*)&m_pcAvatar->m_BasicVectorMod[i],sizeof(m_pcAvatar->m_BasicVectorMod[i]));
  679. }
  680. }
  681. //Loop through the models of currently equipped items
  682. //If two items cover the same area, the one with a higher coverage value supercedes
  683. for ( itObject = m_pcAvatar->m_lstInventory.begin( ); itObject != m_pcAvatar->m_lstInventory.end( ); ++itObject )
  684. {
  685. if ( ( *itObject )->m_fEquipped == 2 )
  686. {
  687. cItemModels *pcItemInv = cItemModels::FindModel(( *itObject )->GetItemModelID());
  688. if ( pcItemInv->m_bWearModelChange != 0)
  689. {
  690. for (int i = 0; i < pcItemInv->m_bWearModelChange; i++)
  691. {
  692. modelIsCovered = false;
  693. for ( iterObject_lst itObject2 = m_pcAvatar->m_lstInventory.begin( ); itObject2 != m_pcAvatar->m_lstInventory.end( ); ++itObject2 )
  694. {
  695. if ( ( *itObject2 )->m_fEquipped == 2 )
  696. {
  697. cItemModels *pcItemInv2 = cItemModels::FindModel(( *itObject2 )->GetItemModelID());
  698. if ( pcItemInv2->m_bWearModelChange != 0)
  699. {
  700. for (int j = 0; j < pcItemInv2->m_bWearModelChange; j++)
  701. {
  702. if (pcItemInv->m_WearVectorMod[i].m_bModelIndex == pcItemInv2->m_WearVectorMod[j].m_bModelIndex)
  703. if (pcItemInv->m_dwCoverage < pcItemInv2->m_dwCoverage)
  704. modelIsCovered = true;
  705. }
  706. }
  707. }
  708. }
  709. if (!modelIsCovered)
  710. cWrChange.pasteData((UCHAR*)&pcItemInv->m_WearVectorMod[i],sizeof(pcItemInv->m_WearVectorMod[i]));
  711. }
  712. }
  713. }
  714. }
  715. cWrChange.pasteAlign(4);
  716. cWrChange << m_pcAvatar->m_wNumLogins;
  717. cWrChange << ++m_pcAvatar->m_wModelSequence;
  718. cWorldManager::SendToAllInFocus(m_pcAvatar->m_Location,cWrChange,3);
  719. //Move Object to Inventory
  720. cMessage cmMoveObjectToInventory1;
  721. cmMoveObjectToInventory1 << 0xF74AL << dwObjectGUID << pcObj->m_wNumLogins << ++pcObj->m_wPositionSequence;
  722. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmMoveObjectToInventory1, 3 );
  723. break;
  724. }
  725. else //If the object was not equipped
  726. {
  727. cMessage cmMoveInventory;
  728. cmMoveInventory << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x22L << dwObjectGUID << m_pcAvatar->GetGUID( ) << dwDestination << 0L;
  729. AddPacket( WORLD_SERVER, cmMoveInventory, 4 );
  730. cMessage cmSetContainer;
  731. cmSetContainer << 0x022DL << ( pcObj->m_bInventorySequence += 2 ) << dwObjectGUID << 2L << m_pcAvatar->GetGUID( );
  732. AddPacket( WORLD_SERVER, cmSetContainer, 4 );
  733. break;
  734. }
  735. }
  736. //If the object is found in the world (non-inventory)
  737. else if( ( pcObj = cWorldManager::FindObject( dwObjectGUID ) ) )
  738. {
  739. //Bend Down Animation
  740. unsigned char ucAnimBendDown[28] = {
  741. 0x4C, 0xF7, 0x00, 0x00, 0xFF, 0xF2, 0x09, 0x50, 0x3C, 0x00, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, //(L÷_____P________) - 0000
  742. 0x00, 0x00, 0x3D, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, //(__=_________) - 0010
  743. };
  744. CopyMemory( &ucAnimBendDown[4], &m_pcAvatar->m_dwGUID, 4 );
  745. CopyMemory( &ucAnimBendDown[8], &m_pcAvatar->m_wNumLogins, 2 );
  746. CopyMemory( &ucAnimBendDown[10], &( ++m_pcAvatar->m_wCurAnim ), 2 );
  747. CopyMemory( &ucAnimBendDown[12], &( ++m_pcAvatar->m_wMeleeSequence ), 2 );
  748. cMessage cmBendDownAnim;
  749. cmBendDownAnim.CannedData( ucAnimBendDown, 28 );
  750. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmBendDownAnim, 3 );
  751. //Insert Inventory Item
  752. cMessage cmInsertInventoryItem;
  753. cmInsertInventoryItem << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x22L << dwObjectGUID << m_pcAvatar->GetGUID( ) << dwDestination << 0L;
  754. AddPacket( WORLD_SERVER, cmInsertInventoryItem, 4 );
  755. //Sound
  756. unsigned char ucSound[16] = {
  757. 0x50, 0xF7, 0x00, 0x00, 0xFF, 0xF2, 0x09, 0x50, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, //(P÷_____Pz______?) - 0000
  758. };
  759. CopyMemory( &ucSound[4], &m_pcAvatar->m_dwGUID, 4 );
  760. cMessage cmSound;
  761. cmSound.CannedData( ucSound, 16 );
  762. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmSound, 3 );
  763. //Standup Animation
  764. unsigned char ucAnimStand[24] = {
  765. 0x4C, 0xF7, 0x00, 0x00, 0xFF, 0xF2, 0x09, 0x50, 0x3C, 0x00, 0x0B, 0x00, 0x05, 0x00, 0x00, 0x00, //(L÷_____P________) - 0000
  766. 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, //(__=_____) - 0010
  767. };
  768. CopyMemory( &ucAnimStand[4], &m_pcAvatar->m_dwGUID, 4 );
  769. CopyMemory( &ucAnimStand[8], &m_pcAvatar->m_wNumLogins, 2 );
  770. CopyMemory( &ucAnimStand[10], &( ++m_pcAvatar->m_wCurAnim ), 2 );
  771. CopyMemory( &ucAnimStand[12], &( ++m_pcAvatar->m_wMeleeSequence ), 2 );
  772. cMessage cmAnimStand;
  773. cmAnimStand.CannedData( ucAnimStand, 24 );
  774. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmAnimStand, 3 );
  775. //Move the object to the avatar's inventory
  776. cMessage cmMoveObjectToInventory;
  777. cmMoveObjectToInventory << 0xF74AL << dwObjectGUID << pcObj->m_wNumLogins << ++pcObj->m_wPositionSequence;
  778. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmMoveObjectToInventory, 3 );
  779. //Save the object to the avatar's inventory in the database
  780. cDatabase::AddToInventoryDB(m_pcAvatar->GetGUID(), pcObj);
  781. //Cubem0j0: see if this even fires...
  782. #ifdef _DEBUG
  783. cMasterServer::ServerMessage(ColorYellow,this,"RemoveObject Fired.");
  784. #endif
  785. cWorldManager::RemoveObject( pcObj, false, false );
  786. m_pcAvatar->AddInventory( pcObj );
  787. break;
  788. }
  789. //Check to see if the item is on a monster corpse
  790. cCorpse *monCorpse = cWorldManager::FindCorpse(m_pcAvatar->m_CorpseTarget);
  791. cObject *monObj = monCorpse->FindInventory(MType3);
  792. //If the object is found on the monster corpse
  793. if( monObj )
  794. {
  795. #ifdef _DEBUG
  796. cMasterServer::ServerMessage( ColorYellow,this,"Corpse id: %d",monCorpse->GetGUID());
  797. #endif
  798. cMessage cmPickUpItem;
  799. cmPickUpItem << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x0022L << MType3
  800. << m_pcAvatar->GetGUID() << 0L << 0L;
  801. AddPacket(WORLD_SERVER,cmPickUpItem, 4);
  802. #ifdef _DEBUG
  803. cMasterServer::ServerMessage( ColorYellow,this,"Object id: %d",monObj->GetGUID());
  804. #endif
  805. monCorpse->RemoveInventory(monObj);
  806. m_pcAvatar->AddInventory(monObj);
  807. break;
  808. }
  809. break; //case 0x0019
  810. }
  811. //Equipping an object
  812. case INVENTORY_EQUIP: //0x001A
  813. {
  814. DWORD dwObjectGUID = MType3;
  815. if ( !dwObjectGUID )
  816. break; //case 0x001A
  817. DWORD dwCoverage = MType4;
  818. //Cubem0j0: Find the model
  819. //Outside of Inventory
  820. //cObject *wObj = cWorldManager::FindObject(dwObjectGUID);
  821. //cItemModels *woItem = cItemModels::FindModel(wObj->GetItemModelID());
  822. //Search inside the avatar's inventory
  823. cObject *pcObj = m_pcAvatar->FindInventory( dwObjectGUID );
  824. //If the object was found in the avatar's inventory
  825. if ( pcObj )
  826. {
  827. cItemModels *pcItem = cItemModels::FindModel(pcObj->GetItemModelID());
  828. pcObj->m_fEquipped = 0;
  829. DWORD dwSequenceB = 0;
  830. BYTE bSequenceA = 0;
  831. bSequenceA = ++pcObj->m_bInventorySequence;
  832. dwSequenceB = bSequenceA + 1;
  833. cMessage cmEquip; // Message 1 Wearing Clothing
  834. cmEquip << 0xF7B0L << m_pcAvatar->m_dwGUID << ++m_dwF7B0Sequence << 0x23L << dwObjectGUID << dwCoverage;
  835. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmEquip, 4 );
  836. //If the object is not a weapon
  837. if (dwCoverage < 0x00100000)
  838. {
  839. cMessage cWrChange;
  840. WORD wModelChangeType = m_pcAvatar->m_wNumLogins;
  841. if (pcItem->m_PortalLinker != 0)
  842. {
  843. if (m_pcAvatar->m_wGender == 0)
  844. cPortalDat::LoadItemModel(pcObj, 0x0200004E);
  845. else
  846. cPortalDat::LoadItemModel(pcObj, 0x02000001);
  847. }
  848. int paletteChange = m_pcAvatar->m_bBasicPaletteChange + pcObj->m_bWearPaletteChange;
  849. int textureChange = m_pcAvatar->m_bBasicTextureChange + pcItem->m_bWearTextureChange;
  850. //Loop through the palettes and textures of previously equipped items
  851. for ( iterObject_lst itObject = m_pcAvatar->m_lstInventory.begin( ); itObject != m_pcAvatar->m_lstInventory.end( ); ++itObject )
  852. {
  853. if ( ( *itObject )->m_fEquipped == 2 )
  854. {
  855. cItemModels *pcItemInv = cItemModels::FindModel(( *itObject )->GetItemModelID());
  856. if ( ( *itObject )->m_bWearPaletteChange != 0)
  857. paletteChange += ( *itObject )->m_bWearPaletteChange;
  858. if ( pcItemInv->m_bWearTextureChange != 0)
  859. textureChange += pcItemInv->m_bWearTextureChange;
  860. }
  861. }
  862. cWrChange << DWORD(0xF625)
  863. << DWORD(m_pcAvatar->m_dwGUID)
  864. << BYTE(0x11) // 11 Vector Palettes
  865. << BYTE(paletteChange)
  866. << BYTE(textureChange)
  867. << BYTE(m_pcAvatar->m_bBasicModelChange);
  868. //cWrChange << m_pcAvatar->m_wPaletteCode;
  869. cWrChange << WORD(0x007E);
  870. //Loop through the avatar's default palettes
  871. if ( m_pcAvatar->m_bBasicPaletteChange != 0)
  872. {
  873. for (int i = 0; i < m_pcAvatar->m_bBasicPaletteChange; i++)
  874. {
  875. cWrChange.pasteData((UCHAR*)&m_pcAvatar->m_BasicVectorPal[i],sizeof(m_pcAvatar->m_BasicVectorPal[i]));
  876. }
  877. }
  878. //Loop through the palettes of previously equipped items
  879. for ( itObject = m_pcAvatar->m_lstInventory.begin( ); itObject != m_pcAvatar->m_lstInventory.end( ); ++itObject )
  880. {
  881. if ( ( *itObject )->m_fEquipped == 2 )
  882. {
  883. cItemModels *pcItemInv = cItemModels::FindModel(( *itObject )->GetItemModelID());
  884. if ( ( *itObject )->m_bWearPaletteChange != 0)
  885. {
  886. for (int i = 0; i < ( *itObject )->m_bWearPaletteChange; i++)
  887. {
  888. cWrChange.pasteData((UCHAR*)&( *itObject )->m_WearVectorPal[i],sizeof(pcItemInv->m_WearVectorPal[i]));
  889. }
  890. }
  891. }
  892. }
  893. //Loop through the palettes of the newly equipped item
  894. if ( pcObj->m_bWearPaletteChange != 0)
  895. {
  896. for (int i = 0; i < pcObj->m_bWearPaletteChange; i++)
  897. {
  898. cWrChange.pasteData((UCHAR*)&pcObj->m_WearVectorPal[i],sizeof(pcItem->m_WearVectorPal[i]));
  899. }
  900. }
  901. //Loop through the avatar's default textures
  902. if ( m_pcAvatar->m_bBasicTextureChange != 0)
  903. {
  904. for (int i = 0; i < m_pcAvatar->m_bBasicTextureChange; i++)
  905. {
  906. cWrChange.pasteData((UCHAR*)&m_pcAvatar->m_BasicVectorTex[i],sizeof(m_pcAvatar->m_BasicVectorTex[i]));
  907. }
  908. }
  909. //Loop through the textures of previously equipped items
  910. for ( itObject = m_pcAvatar->m_lstInventory.begin( ); itObject != m_pcAvatar->m_lstInventory.end( ); ++itObject )
  911. {
  912. if ( ( *itObject )->m_fEquipped == 2 )
  913. {
  914. cItemModels *pcItemInv = cItemModels::FindModel(( *itObject )->GetItemModelID());
  915. if ( pcItemInv->m_bWearTextureChange != 0)
  916. {
  917. for (int i = 0; i < pcItemInv->m_bWearTextureChange; i++)
  918. {
  919. cWrChange.pasteData((UCHAR*)&pcItemInv->m_WearVectorTex[i],sizeof(pcItemInv->m_WearVectorTex[i]));
  920. }
  921. }
  922. }
  923. }
  924. //Loop through the textures of the newly equipped item
  925. if ( pcItem->m_bWearTextureChange != 0)
  926. {
  927. for (int i = 0; i < pcItem->m_bWearTextureChange; i++)
  928. {
  929. cWrChange.pasteData((UCHAR*)&pcItem->m_WearVectorTex[i],sizeof(pcItem->m_WearVectorTex[i]));
  930. }
  931. }
  932. //The avatar always consists of seveteen (0x11) submodels. Only the model of the top- or outer-most
  933. //object is sent. Similarly, it must be checked which if any avatar sub-models are covered by item
  934. //models as well as which item models are covered by other item models.
  935. bool modelIsCovered;
  936. if ( m_pcAvatar->m_bBasicModelChange != 0)
  937. {
  938. //Loop through the avatar's default models
  939. //Do not include avatar models superceded by item models
  940. for (int i = 0; i < m_pcAvatar->m_bBasicModelChange; i++)
  941. {
  942. modelIsCovered = false;
  943. //Loop through the models of previously equipped items
  944. for ( itObject = m_pcAvatar->m_lstInventory.begin( ); itObject != m_pcAvatar->m_lstInventory.end( ); ++itObject )
  945. {
  946. if ( ( *itObject )->m_fEquipped == 2 )
  947. {
  948. cItemModels *pcItemInv = cItemModels::FindModel(( *itObject )->GetItemModelID());
  949. if ( pcItemInv->m_bWearModelChange != 0)
  950. {
  951. for (int j = 0; j < pcItemInv->m_bWearModelChange; j++)
  952. {
  953. //Find whether the item affects the given avatar body part
  954. //If so, the item model index will equal the given avatar model index
  955. if(m_pcAvatar->m_BasicVectorMod[i].m_bModelIndex == pcItemInv->m_WearVectorMod[j].m_bModelIndex)
  956. {
  957. modelIsCovered = true;
  958. }
  959. }
  960. }
  961. }
  962. }
  963. //Loop through the models of the newly equipped item
  964. for (int j = 0; j < pcItem->m_bWearModelChange; j++)
  965. {
  966. //Find whether the item affects the given avatar body part
  967. //If so, the item model index will equal the given avatar model index
  968. if(m_pcAvatar->m_BasicVectorMod[i].m_bModelIndex == pcItem->m_WearVectorMod[j].m_bModelIndex)
  969. {
  970. modelIsCovered = true;
  971. }
  972. }
  973. if (!modelIsCovered)
  974. cWrChange.pasteData((UCHAR*)&m_pcAvatar->m_BasicVectorMod[i],sizeof(m_pcAvatar->m_BasicVectorMod[i]));
  975. }
  976. }
  977. //Loop through the models of currently equipped items
  978. //If two items cover the same area, the one with a higher coverage value supercedes
  979. for ( itObject = m_pcAvatar->m_lstInventory.begin( ); itObject != m_pcAvatar->m_lstInventory.end( ); ++itObject )
  980. {
  981. if ( ( *itObject )->m_fEquipped == 2 )
  982. {
  983. cItemModels *pcItemInv = cItemModels::FindModel(( *itObject )->GetItemModelID());
  984. if ( pcItemInv->m_bWearModelChange != 0)
  985. {
  986. for (int i = 0; i < pcItemInv->m_bWearModelChange; i++)
  987. {
  988. modelIsCovered = false;
  989. //Compare the inventory item against all other inventory items
  990. for ( iterObject_lst itObject2 = m_pcAvatar->m_lstInventory.begin( ); itObject2 != m_pcAvatar->m_lstInventory.end( ); ++itObject2 )
  991. {
  992. if ( ( *itObject2 )->m_fEquipped == 2 )
  993. {
  994. cItemModels *pcItemInv2 = cItemModels::FindModel(( *itObject2 )->GetItemModelID());
  995. if ( pcItemInv2->m_bWearModelChange != 0)
  996. {
  997. for (int j = 0; j < pcItemInv2->m_bWearModelChange; j++)
  998. {
  999. //Compare the current inventory item against another inventory item
  1000. if (pcItemInv->m_WearVectorMod[i].m_bModelIndex == pcItemInv2->m_WearVectorMod[j].m_bModelIndex)
  1001. if (pcItemInv->m_dwCoverage < pcItemInv2->m_dwCoverage)
  1002. modelIsCovered = true;
  1003. }
  1004. }
  1005. }
  1006. }
  1007. for (int j = 0; j < pcItem->m_bWearModelChange; j++)
  1008. {
  1009. //Compare the inventory item against the newly equipped item
  1010. if (pcItemInv->m_WearVectorMod[i].m_bModelIndex == pcItem->m_WearVectorMod[j].m_bModelIndex)
  1011. if (pcItemInv->m_dwCoverage < pcItem->m_dwCoverage)
  1012. modelIsCovered = true;
  1013. }
  1014. if (!modelIsCovered)
  1015. cWrChange.pasteData((UCHAR*)&pcItemInv->m_WearVectorMod[i],sizeof(pcItemInv->m_WearVectorMod[i]));
  1016. }
  1017. }
  1018. }
  1019. }
  1020. //Loop through the models of the newly equipped item
  1021. for (int i = 0; i < pcItem->m_bWearModelChange; i++)
  1022. {
  1023. modelIsCovered = false;
  1024. //Loop through the models of currently equipped items
  1025. for ( itObject = m_pcAvatar->m_lstInventory.begin( ); itObject != m_pcAvatar->m_lstInventory.end( ); ++itObject )
  1026. {
  1027. if ( ( *itObject )->m_fEquipped == 2 )
  1028. {
  1029. cItemModels *pcItemInv = cItemModels::FindModel(( *itObject )->GetItemModelID());
  1030. if ( pcItemInv->m_bWearModelChange != 0)
  1031. {
  1032. for (int j = 0; j < pcItemInv->m_bWearModelChange; j++)
  1033. {
  1034. //Compare the inventory item against the newly equipped item
  1035. if (pcItem->m_WearVectorMod[i].m_bModelIndex == pcItemInv->m_WearVectorMod[j].m_bModelIndex)
  1036. if (pcItem->m_dwCoverage < pcItemInv->m_dwCoverage)
  1037. modelIsCovered = true;
  1038. }
  1039. }
  1040. }
  1041. }
  1042. if (!modelIsCovered)
  1043. cWrChange.pasteData((UCHAR*)&pcItem->m_WearVectorMod[i],sizeof(pcItem->m_WearVectorMod[i]));
  1044. }
  1045. pcObj->m_fEquipped = 2;
  1046. char szCommand[255];
  1047. RETCODE retcode;
  1048. sprintf( szCommand, "UPDATE items_instance_inventory SET Equipped = %d WHERE GUID = %lu AND OwnerGUID = %lu;",pcObj->m_fEquipped,dwObjectGUID,m_pcAvatar->GetGUID() );
  1049. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  1050. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  1051. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_CLOSE ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  1052. cWrChange.pasteAlign(4);
  1053. cWrChange << m_pcAvatar->m_wNumLogins;
  1054. cWrChange << ++m_pcAvatar->m_wModelSequence;
  1055. cWorldManager::SendToAllInFocus(m_pcAvatar->m_Location,cWrChange,3);
  1056. /*
  1057. cMessage cmEquip2; // First 022D Set Container to 0
  1058. cmEquip2 << 0x022DL << ++m_pcAvatar->m_bWearSeq << dwObjectGUID << 0x02L << 0x0L;
  1059. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmEquip2, 3 );
  1060. cMessage cmEquip3; // Second 022D Set Wielder to Avatar's
  1061. cmEquip3 << 0x022DL << ++m_pcAvatar->m_bWearSeq << dwObjectGUID << 0x03L << m_pcAvatar->m_dwGUID;
  1062. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmEquip3, 3 );
  1063. cMessage cmEquip229; // 0229 Set Coverage
  1064. cmEquip229 << 0x0229L << ++m_pcAvatar->m_bWearSeq << dwObjectGUID << 0x0AL << dwCoverage;
  1065. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmEquip229, 3 );
  1066. cMessage cmActionComplete;
  1067. cmActionComplete << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x01C7L << 0L;
  1068. AddPacket(WORLD_SERVER,cmActionComplete,4);
  1069. */
  1070. }
  1071. //If the object is a weapon (sword, wand, bow, etc.)
  1072. if ((dwCoverage == 0x00100000) || (dwCoverage == 0x01000000))
  1073. {
  1074. cMessage cmWieldObject;
  1075. cmWieldObject << 0xF749L << m_pcAvatar->GetGUID( ) << dwObjectGUID << 1L << 1L << m_pcAvatar->m_wNumLogins << ++pcObj->m_wPositionSequence;
  1076. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmWieldObject, 3 );
  1077. AddPacket( WORLD_SERVER, cmWieldObject, 4 );
  1078. m_pcAvatar->myWeapon = reinterpret_cast <cWeapon *>(m_pcAvatar->FindInventory(dwObjectGUID));
  1079. m_pcAvatar->myWeapon->m_fEquipped = 1;
  1080. }
  1081. //Shields
  1082. else if (dwCoverage == 0x00200000)
  1083. {
  1084. cMessage cmWieldObject;
  1085. cmWieldObject << 0xF749L << m_pcAvatar->GetGUID( ) << dwObjectGUID << 3L << 6L << m_pcAvatar->m_wNumLogins << ++pcObj->m_wPositionSequence;
  1086. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmWieldObject, 3 );
  1087. AddPacket( WORLD_SERVER, cmWieldObject, 4 );
  1088. m_pcAvatar->myShield = reinterpret_cast <cShield *>(m_pcAvatar->FindInventory(dwObjectGUID));
  1089. m_pcAvatar->myShield->m_fEquipped = 1;
  1090. m_pcAvatar->Armor_Level += m_pcAvatar->myShield->m_dwArmorLevel;
  1091. }
  1092. //Missile Weapons
  1093. else if (dwCoverage == 0x00400000)
  1094. {
  1095. cMessage cmWieldObject;
  1096. cmWieldObject << 0xF749L << m_pcAvatar->GetGUID( ) << dwObjectGUID << 2L << 3L << m_pcAvatar->m_wNumLogins << ++pcObj->m_wPositionSequence;
  1097. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmWieldObject, 3 );
  1098. AddPacket( WORLD_SERVER, cmWieldObject, 4 );
  1099. pcMW = reinterpret_cast <cAmmo *>(m_pcAvatar->FindInventory(dwObjectGUID));
  1100. pcMW->m_fEquipped = 1;
  1101. }
  1102. break;
  1103. }
  1104. //If the object is found in the world (non-inventory)
  1105. if ( ( pcObj = cWorldManager::FindObject( dwObjectGUID ) ) )
  1106. {
  1107. pcObj->m_fEquipped = 1;
  1108. unsigned char ucAnimBendDown[28] = {
  1109. 0x4C, 0xF7, 0x00, 0x00, 0xD6, 0xFD, 0x09, 0x50, 0x08, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, //(L÷___ý_P________) - 0000
  1110. 0x00, 0x00, 0x3D, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, //(__=_________) - 0010
  1111. };
  1112. cWorldManager::SendToAllInFocus(m_pcAvatar->m_Location,m_pcAvatar->SoundEffect(122),3);
  1113. cMessage cmEquip;
  1114. cmEquip << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x23L << dwObjectGUID << dwCoverage;
  1115. AddPacket( WORLD_SERVER, cmEquip, 4 );
  1116. unsigned char ucAnimStandUp[24] = {
  1117. 0x4C, 0xF7, 0x00, 0x00, 0xD6, 0xFD, 0x09, 0x50, 0x08, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, //(L÷___ý_P________) - 0000
  1118. 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, //(__=_____) - 0010
  1119. };
  1120. cWorldManager::SendToAllInFocus(m_pcAvatar->m_Location,m_pcAvatar->SoundEffect(119),3);
  1121. cMessage cmMoveObjectToInventory;
  1122. cmMoveObjectToInventory << 0xF74AL << dwObjectGUID << pcObj->m_wNumLogins << ++pcObj->m_wPositionSequence;
  1123. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmMoveObjectToInventory, 3 );
  1124. cWorldManager::RemoveObject( pcObj, FALSE, FALSE );
  1125. m_pcAvatar->AddInventory( pcObj );
  1126. DWORD dwSequenceB = 0;
  1127. BYTE bSequenceA = 0;
  1128. bSequenceA = ++pcObj->m_bInventorySequence;
  1129. dwSequenceB = bSequenceA + 1;
  1130. //k109: Equip item by picking it up from the ground to your weapon slot.
  1131. if ((dwCoverage == 0x00100000) || (dwCoverage == 0x01000000))
  1132. {
  1133. //Wield Object
  1134. cMessage cmWieldObject;
  1135. cmWieldObject << 0xF749L << m_pcAvatar->GetGUID( ) << dwObjectGUID << 1L << 1L << m_pcAvatar->m_wNumLogins << ++pcObj->m_wPositionSequence;
  1136. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmWieldObject, 3 );
  1137. //pcW = reinterpret_cast <cWeapon *>(m_pcAvatar->FindInventory(dwObjectGUID));
  1138. m_pcAvatar->myWeapon = reinterpret_cast <cWeapon *>(m_pcAvatar->FindInventory(dwObjectGUID));
  1139. //m_pcAvatar->myWeapon = pcW;
  1140. m_pcAvatar->myWeapon->m_fEquipped = 1;
  1141. }
  1142. //Shields
  1143. else if (dwCoverage == 0x00200000)
  1144. {
  1145. cMessage cmWieldObject;
  1146. cmWieldObject << 0xF749L << m_pcAvatar->GetGUID( ) << dwObjectGUID << 3L << 6L << m_pcAvatar->m_wNumLogins << ++pcObj->m_wPositionSequence;
  1147. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmWieldObject, 3 );
  1148. AddPacket( WORLD_SERVER, cmWieldObject, 4 );
  1149. m_pcAvatar->myShield = reinterpret_cast <cShield *>(m_pcAvatar->FindInventory(dwObjectGUID));
  1150. m_pcAvatar->myShield->m_fEquipped = 1;
  1151. m_pcAvatar->Armor_Level += m_pcAvatar->myShield->m_dwArmorLevel;
  1152. }
  1153. //Missile Weapons
  1154. else if (dwCoverage == 0x00400000)
  1155. {
  1156. cMessage cmWieldObject;
  1157. cmWieldObject << 0xF749L << m_pcAvatar->GetGUID( ) << dwObjectGUID << 2L << 3L << m_pcAvatar->m_wNumLogins << ++pcObj->m_wPositionSequence;
  1158. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmWieldObject, 3 );
  1159. AddPacket( WORLD_SERVER, cmWieldObject, 4 );
  1160. pcMW = reinterpret_cast <cAmmo *>(m_pcAvatar->FindInventory(dwObjectGUID));
  1161. pcMW->m_fEquipped = 1;
  1162. }
  1163. }
  1164. break; // case 0x001A
  1165. }
  1166. //Dropping an object
  1167. case INVENTORY_DROP: //0x001B
  1168. {
  1169. DWORD dwObjectGUID = *( DWORD * )&pbData[12];
  1170. if ( !dwObjectGUID )
  1171. break; //case 0x001B
  1172. cObject *pcObj = m_pcAvatar->FindInventory( dwObjectGUID );
  1173. if ( !pcObj )
  1174. break; //case 0x001B
  1175. //Bend Down Animation
  1176. unsigned char ucAnimBendDown[28] = {
  1177. 0x4C, 0xF7, 0x00, 0x00, 0xFF, 0xF2, 0x09, 0x50, 0x3C, 0x00, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, //(L÷_____P________) - 0000
  1178. 0x00, 0x00, 0x3D, 0x00, 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, //(__=_________) - 0010
  1179. };
  1180. CopyMemory( &ucAnimBendDown[4], &m_pcAvatar->m_dwGUID, 4 );
  1181. CopyMemory( &ucAnimBendDown[8], &m_pcAvatar->m_wNumLogins, 2 );
  1182. CopyMemory( &ucAnimBendDown[10], &( ++m_pcAvatar->m_wCurAnim ), 2 );
  1183. CopyMemory( &ucAnimBendDown[12], &( ++m_pcAvatar->m_wMeleeSequence ), 2 );
  1184. cMessage cmBendDownAnim;
  1185. cmBendDownAnim.CannedData( ucAnimBendDown, 28 );
  1186. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmBendDownAnim, 3 );
  1187. //Drop From Inventory
  1188. cMessage cmDropFromInventory;
  1189. cmDropFromInventory << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x019AL << dwObjectGUID;
  1190. AddPacket( WORLD_SERVER, cmDropFromInventory, 4 );
  1191. //Sound
  1192. unsigned char ucSound[16] = {
  1193. 0x50, 0xF7, 0x00, 0x00, 0xFF, 0xF2, 0x09, 0x50, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, //(P÷_____P_______?) - 0000
  1194. };
  1195. CopyMemory( &ucSound[4], &m_pcAvatar->m_dwGUID, 4 );
  1196. cMessage cmSound;
  1197. cmSound.CannedData( ucSound, 16 );
  1198. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmSound, 3 );
  1199. //Standup Animation
  1200. unsigned char ucAnimStand[24] = {
  1201. 0x4C, 0xF7, 0x00, 0x00, 0xFF, 0xF2, 0x09, 0x50, 0x3C, 0x00, 0x0B, 0x00, 0x05, 0x00, 0x00, 0x00, //(L÷_____P________) - 0000
  1202. 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, //(__=_____) - 0010
  1203. };
  1204. CopyMemory( &ucAnimStand[4], &m_pcAvatar->m_dwGUID, 4 );
  1205. CopyMemory( &ucAnimStand[8], &m_pcAvatar->m_wNumLogins, 2 );
  1206. CopyMemory( &ucAnimStand[10], &(++m_pcAvatar->m_wCurAnim), 2 );
  1207. CopyMemory( &ucAnimStand[12], &(++m_pcAvatar->m_wMeleeSequence), 2 );
  1208. cMessage cmAnimStand;
  1209. cmAnimStand.CannedData( ucAnimStand, 24 );
  1210. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmAnimStand, 3 );
  1211. //Set Position
  1212. BYTE MV[] = {
  1213. 0x48, 0xF7, 0x00, 0x00, 0xF9, 0x6C, 0xD3, 0x95, 0x36, 0x00, 0x00, 0x00, 0x6C, 0x01, 0x7E, 0x01,
  1214. 0xF7, 0x4F, 0xCF, 0x41, 0x03, 0xA6, 0xE0, 0xC2, 0xC5, 0x20, 0x30, 0x3D, 0xB9, 0x7E, 0x0D, 0xBF,
  1215. 0xC4, 0x57, 0x55, 0xBF, 0x65, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x09, 0x00, 0x02, 0x00, 0x00, 0x00
  1216. };
  1217. CopyMemory( &MV[4], &dwObjectGUID, 4 );
  1218. CopyMemory( &MV[12], &m_pcAvatar->m_Location, 20 );
  1219. CopyMemory( &MV[32], &m_pcAvatar->m_Location.m_flW, 4 );
  1220. CopyMemory( &MV[0x28], &m_pcAvatar->m_wNumLogins, 2 );
  1221. CopyMemory( &MV[0x2A], &( pcObj->m_wPositionSequence += 4 ), 2 );
  1222. CopyMemory( &MV[0x2C], &( ++pcObj->m_wNumPortals ), 2 );
  1223. cMessage cmSetPosition;
  1224. cmSetPosition.CannedData( MV, sizeof( MV ) );
  1225. pcObj->SetLocation( m_pcAvatar->m_Location );
  1226. m_pcAvatar->RemoveInventory( pcObj );
  1227. cDatabase::RemoveFromInventoryDB(m_pcAvatar->GetGUID(), pcObj->GetGUID());
  1228. cWorldManager::AddObject( pcObj, FALSE );
  1229. cWorldManager::SendToOthersInFocus( m_pcAvatar->m_Location, this, pcObj->CreatePacket( ), 3 );
  1230. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmSetPosition, 3 );
  1231. break; //case 0x001B
  1232. }
  1233. case SWEAR_ALLEGIANCE: //0x001D
  1234. {
  1235. DWORD dwSwearToPlayerGUID;
  1236. CopyMemory( &dwSwearToPlayerGUID, &pbData[12], 4 );
  1237. bool canSwear = false;
  1238. // If the avatar is in an allegiance
  1239. if (m_pcAvatar->m_dwAllegianceID != 0)
  1240. {
  1241. cAllegiance* aAllegiance = cAllegiance::GetAllegianceByID(m_pcAvatar->GetAllegianceID());
  1242. if (aAllegiance)
  1243. {
  1244. Member* thisMember = aAllegiance->FindMember(m_pcAvatar->GetGUID());
  1245. if (thisMember)
  1246. if (thisMember->m_dwPatron == 0) // if the avatar has no patron
  1247. canSwear = true;
  1248. }
  1249. }
  1250. // If the avatar is not in an allegiance
  1251. if (m_pcAvatar->m_dwAllegianceID == 0)
  1252. {
  1253. canSwear = true;
  1254. }
  1255. if (canSwear)
  1256. {
  1257. // Find the recipient
  1258. cClient *pcRecvClient = cClient::FindClient( dwSwearToPlayerGUID );
  1259. if (pcRecvClient)
  1260. {
  1261. cAvatar *pc_RecvAvatar = pcRecvClient->m_pcAvatar;
  1262. if (pc_RecvAvatar)
  1263. {
  1264. // Open the recipient avatar's confirmation panel
  1265. pcRecvClient->AddPacket( WORLD_SERVER, pc_RecvAvatar->ConfirmPanelRequest(++m_dwF7B0Sequence,1,cWorldManager::NewConfirmSeq(),m_pcAvatar->Name()), 4 );
  1266. // Add the allegiance request to the pending confirmation queue
  1267. cWorldManager::AddPendingConfirm(cWorldManager::CurrentConfirmSeq(),1,m_pcAvatar->Name(),m_pcAvatar->GetGUID(),pc_RecvAvatar->GetGUID());
  1268. }
  1269. }
  1270. }
  1271. break;
  1272. }
  1273. case BREAK_ALLEGIANCE: //0x001E
  1274. {
  1275. DWORD dwPatronGUID = MType3;
  1276. m_pcAvatar->BreakAllegiance(dwPatronGUID);
  1277. break;
  1278. }
  1279. case ALLEGIANCE_PANEL: //0x001F
  1280. {
  1281. //cMessage cmAllegiance;
  1282. //cmAllegiance << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x0020L << 0L << 0L << 0L;
  1283. //AddPacket(WORLD_SERVER,cmAllegiance,4);
  1284. AddPacket(WORLD_SERVER,m_pcAvatar->AllegianceInfo(++m_dwF7B0Sequence),4);
  1285. cMessage cmActionComplete;
  1286. cmActionComplete << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x01C7L << 0L;
  1287. AddPacket( WORLD_SERVER,cmActionComplete,4);
  1288. break;
  1289. }
  1290. //Direct /tells to known avatars
  1291. case SEND_TELL_GUID: //0x0032
  1292. {
  1293. BYTE *bTextLength = &pbData[12];
  1294. WORD wTextLength = pbData[12];
  1295. char *szMessageText = new char[wTextLength];
  1296. CopyMemory( szMessageText, &pbData[14], wTextLength );
  1297. szMessageText[wTextLength] = '\0';
  1298. //( char * )&bTextLength[2]
  1299. cMasterServer::SendTell( szMessageText, cClient::FindClient( *(DWORD *)(pbData + ((FH.m_wFragmentLength - sizeof( cFragmentHeader )) - sizeof( DWORD ))) ), this );
  1300. break; // case 0x0032
  1301. }
  1302. case TARGET_USE: //0x0035
  1303. {
  1304. cObject *pcObj = m_pcAvatar->FindInventory( MType3 );
  1305. cObject* pcTargetObj = cWorldManager::FindObject( MType3 );
  1306. if( pcObj )
  1307. {
  1308. pcObj->Action(this);
  1309. cMessage cmActionComplete;
  1310. cmActionComplete << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x01C7L << 0L;
  1311. AddPacket( WORLD_SERVER,cmActionComplete,4);
  1312. break;
  1313. }
  1314. else
  1315. {
  1316. //do nothing!
  1317. break;
  1318. }
  1319. }
  1320. case USE: //0x0036
  1321. {
  1322. //TODO: Add item type implementation here.
  1323. //Outside inventory
  1324. DWORD dwTargetGUID = *( DWORD * )&pbData[12];
  1325. //Inside inventory
  1326. DWORD dwObjectGUID = *( DWORD * )&pbData[12];
  1327. NPCID = *( DWORD * )&pbData[12];
  1328. CORPSEID = *( DWORD * )&pbData[12];
  1329. cObject* pcTargetObj = cWorldManager::FindObject( dwTargetGUID );
  1330. cObject *pcObj = m_pcAvatar->FindInventory( dwObjectGUID );
  1331. if( pcObj )
  1332. {
  1333. pcObj->Action(this);
  1334. cMessage cmActionComplete;
  1335. cmActionComplete << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x01C7L << 0L;
  1336. AddPacket( WORLD_SERVER,cmActionComplete,4);
  1337. break;
  1338. }
  1339. if( pcTargetObj )
  1340. {
  1341. intRange = m_pcAvatar->GetRange( m_pcAvatar->m_Location.m_dwLandBlock,m_pcAvatar->m_Location.m_flX,m_pcAvatar->m_Location.m_flY,m_pcAvatar->m_Location.m_flZ, pcTargetObj->m_Location.m_dwLandBlock, pcTargetObj->m_Location.m_flX, pcTargetObj->m_Location.m_flY, pcTargetObj->m_Location.m_flZ );
  1342. //debug
  1343. #ifdef _DEBUG
  1344. char szPacket[60];
  1345. sprintf( szPacket, "Range is: %f",intRange);
  1346. cMasterServer::ServerMessage( ColorYellow,this,(char *)szPacket);
  1347. #endif
  1348. if (intRange < 0.5)
  1349. {
  1350. pcTargetObj->Action(this);
  1351. break;
  1352. }
  1353. else
  1354. {
  1355. //pcTargetObj->Assess(this);
  1356. char szPacket[60];
  1357. sprintf( szPacket, "That object is to far away to use!");
  1358. cMasterServer::ServerMessage( ColorYellow,this,(char *)szPacket);
  1359. cMessage cmActionComplete;
  1360. cmActionComplete << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x01C7L << 0L;
  1361. AddPacket( WORLD_SERVER,cmActionComplete,4);
  1362. break;
  1363. }
  1364. }
  1365. else
  1366. {
  1367. break;
  1368. }
  1369. break;
  1370. }
  1371. case RAISE_VITAL: //0x0044
  1372. {
  1373. switch(MType3)
  1374. {
  1375. case 0x00000001: //Health
  1376. {
  1377. AddPacket( WORLD_SERVER,m_pcAvatar->RaiseHealth(MType4),4);
  1378. //The client automatically updates the displayed health value.
  1379. }
  1380. break;
  1381. case 0x00000003: //Stamina
  1382. {
  1383. AddPacket( WORLD_SERVER,m_pcAvatar->RaiseStamina(MType4),4);
  1384. //The client automatically updates the displayed stamina value.
  1385. }
  1386. break;
  1387. case 0x00000005: //Mana
  1388. {
  1389. AddPacket( WORLD_SERVER,m_pcAvatar->RaiseMana(MType4),4);
  1390. //The client automatically updates the displayed mana value.
  1391. }
  1392. break;
  1393. }
  1394. //Raising each vital consumes experience, thereby reducing unassigned experience
  1395. //Send the Unassigned Experience message to update the client.
  1396. AddPacket( WORLD_SERVER, m_pcAvatar->DecrementUnassignedExp(MType4), 4 );
  1397. break;
  1398. }
  1399. case RAISE_ATTRIBUTE: //0x0045
  1400. {
  1401. switch(MType3)
  1402. {
  1403. case 0x00000001: //Strength
  1404. {
  1405. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateStrength(MType4),4);
  1406. }
  1407. break;
  1408. case 0x00000002: //Endurance
  1409. {
  1410. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateEndurance(MType4),4);
  1411. //When endurance is raised:
  1412. // 1. Stamina should always increase by 1.
  1413. // 2. Health should increase by 1 for every 2 points spent.
  1414. //The client automatically updates these values as needed.
  1415. }
  1416. break;
  1417. case 0x00000003: //Quickness
  1418. {
  1419. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateQuickness(MType4),4);
  1420. }
  1421. break;
  1422. case 0x00000004: //Coordination
  1423. {
  1424. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateCoordination(MType4),4);
  1425. }
  1426. break;
  1427. case 0x00000005: //Focus
  1428. {
  1429. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateFocus(MType4),4);
  1430. }
  1431. break;
  1432. case 0x00000006: //Self
  1433. {
  1434. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSelf(MType4),4);
  1435. //When self is raised, mana should always increase by 1.
  1436. //The client automatically updates this value as needed.
  1437. }
  1438. break;
  1439. }
  1440. //Raising each attribute consumes experience, thereby reducing unassigned experience
  1441. //Send the Unassigned Experience message to update the client.
  1442. AddPacket( WORLD_SERVER, m_pcAvatar->DecrementUnassignedExp(MType4), 4 );
  1443. break;
  1444. }
  1445. case RAISE_SKILL: //0x0046
  1446. {
  1447. //Update the skills
  1448. switch(MType3)
  1449. {
  1450. case AXE:
  1451. {
  1452. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1453. }
  1454. break;
  1455. case BOW:
  1456. {
  1457. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1458. }
  1459. break;
  1460. case CROSSBOW:
  1461. {
  1462. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1463. }
  1464. break;
  1465. case DAGGER:
  1466. {
  1467. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1468. }
  1469. break;
  1470. case MACE:
  1471. {
  1472. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1473. }
  1474. break;
  1475. case MELEE_DEFENSE:
  1476. {
  1477. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1478. }
  1479. break;
  1480. case MISSILE_DEFENSE:
  1481. {
  1482. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1483. }
  1484. break;
  1485. case SPEAR:
  1486. {
  1487. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1488. }
  1489. break;
  1490. case STAFF:
  1491. {
  1492. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1493. }
  1494. break;
  1495. case SWORD:
  1496. {
  1497. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1498. }
  1499. break;
  1500. case THROWN_WEAPONS:
  1501. {
  1502. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1503. }
  1504. break;
  1505. case UNARMED_COMBAT:
  1506. {
  1507. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1508. }
  1509. break;
  1510. case ARCANE_LORE:
  1511. {
  1512. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1513. }
  1514. break;
  1515. case MAGIC_DEFENSE:
  1516. {
  1517. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1518. }
  1519. break;
  1520. case MANA_CONVERSION:
  1521. {
  1522. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1523. }
  1524. break;
  1525. case ITEM_TINKERING:
  1526. {
  1527. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1528. }
  1529. break;
  1530. case ASSESS_PERSON:
  1531. {
  1532. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1533. }
  1534. break;
  1535. case DECEPTION:
  1536. {
  1537. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1538. }
  1539. break;
  1540. case HEALING:
  1541. {
  1542. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1543. }
  1544. break;
  1545. case S_JUMP:
  1546. {
  1547. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1548. }
  1549. break;
  1550. case LOCKPICK:
  1551. {
  1552. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1553. }
  1554. break;
  1555. case RUN:
  1556. {
  1557. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1558. }
  1559. break;
  1560. case ASSESS_CREATURE:
  1561. {
  1562. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1563. }
  1564. break;
  1565. case WEAPON_TINKERING:
  1566. {
  1567. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1568. }
  1569. break;
  1570. case ARMOR_TINKERING:
  1571. {
  1572. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1573. }
  1574. break;
  1575. case MAGIC_ITEM_TINKERING:
  1576. {
  1577. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1578. }
  1579. break;
  1580. case CREATURE_ENCHANTMENT:
  1581. {
  1582. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1583. }
  1584. break;
  1585. case ITEM_ENCHANTMENT:
  1586. {
  1587. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1588. }
  1589. break;
  1590. case LIFE_MAGIC:
  1591. {
  1592. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1593. }
  1594. break;
  1595. case WAR_MAGIC:
  1596. {
  1597. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1598. }
  1599. break;
  1600. case LEADERSHIP:
  1601. {
  1602. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1603. }
  1604. break;
  1605. case LOYALTY:
  1606. {
  1607. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1608. }
  1609. break;
  1610. case FLETCHING:
  1611. {
  1612. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1613. }
  1614. break;
  1615. case ALCHEMY:
  1616. {
  1617. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1618. }
  1619. break;
  1620. case COOKING:
  1621. {
  1622. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1623. }
  1624. break;
  1625. case SALVAGING:
  1626. {
  1627. AddPacket( WORLD_SERVER,m_pcAvatar->UpdateSkill(MType3,MType4),4);
  1628. }
  1629. break;
  1630. }
  1631. //Raising each skill consumes experience, thereby reducing unassigned experience
  1632. //Send the Unassigned Experience message to update the client.
  1633. AddPacket( WORLD_SERVER, m_pcAvatar->DecrementUnassignedExp(MType4), 4 );
  1634. break;
  1635. }
  1636. case TRAIN_SKILL: //0x0047
  1637. {
  1638. break;
  1639. }
  1640. case CAST_SPELL_NO_TARGET: //0x0048
  1641. {
  1642. #ifdef _DEBUG
  1643. char szPacket[60];
  1644. sprintf( szPacket, "F7B1 Packet: %08x",MType2);
  1645. cMasterServer::ServerMessage( ColorYellow,this,(char *)szPacket);
  1646. #endif
  1647. break;
  1648. }
  1649. //The client performs a magic attack
  1650. case CAST_SPELL_TARGET: //0x004A
  1651. {
  1652. DWORD *pdwData = (DWORD *)pbData;
  1653. DWORD dwMagTarget;
  1654. DWORD dwSpellID;
  1655. float flTargetHeading;
  1656. DWORD dwSequenceSpell;
  1657. int iTurnTime;
  1658. dwSequenceSpell = pdwData[1];
  1659. dwMagTarget = pdwData[3];
  1660. dwSpellID = pdwData[4];
  1661. if ( m_pcAvatar->m_fIsCasting )
  1662. {
  1663. cMessage cmBusy;
  1664. cmBusy << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x028AL << 0x001DL;
  1665. AddPacket( WORLD_SERVER,cmBusy,4);
  1666. cMessage cmActionComplete;
  1667. cmActionComplete << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x01C7L << 0L;
  1668. AddPacket( WORLD_SERVER,cmActionComplete,4);
  1669. break;
  1670. }
  1671. m_pcAvatar->m_fIsCasting = true;
  1672. #ifdef _DEBUG
  1673. char szPacketCast[100];
  1674. sprintf( szPacketCast, "Spell Sequence: %d -- Spell Casting: %d ",dwSequenceSpell,dwSpellID);
  1675. cMasterServer::ServerMessage( ColorGreen,this,(char *)szPacketCast);
  1676. #endif
  1677. cClient* pcTargetObj = cClient::FindClient( dwMagTarget );
  1678. cSpell *pcSpell = cSpell::FindSpell( dwSpellID );
  1679. if (pcSpell)
  1680. {
  1681. int iNewMana;
  1682. iNewMana = m_pcAvatar->m_cStats.m_lpcVitals[2].m_lTrueCurrent;
  1683. iNewMana -= pcSpell->m_dwManaCost;
  1684. if (iNewMana < 0)
  1685. iNewMana = 0;
  1686. cMessage cmManaLoss = m_pcAvatar->DecrementMana( pcSpell->m_dwManaCost, iNewMana );
  1687. this->AddPacket( WORLD_SERVER, cmManaLoss, 4 );
  1688. }
  1689. if ( pcSpell->m_flUnkFloat1 != 0 )
  1690. {
  1691. //If no client is found (in which case the target is NOT another player)
  1692. if( !pcTargetObj )
  1693. {
  1694. cObject* pcTargetObject = cWorldManager::FindObject( dwMagTarget );
  1695. if( !pcTargetObject )
  1696. {
  1697. flTargetHeading = 0.0f;
  1698. }
  1699. else
  1700. {
  1701. flTargetHeading = cPhysics::GetHeadingTarget(m_pcAvatar->m_Location,pcTargetObject->m_Location);
  1702. #ifdef _DEBUG
  1703. sprintf( szPacketCast, "TargetHeading: %f, flA: %f, flW: %f, Heading: %f",flTargetHeading, m_pcAvatar->m_Location.m_flA, m_pcAvatar->m_Location.m_flW, cPhysics::GetAvatarHeading( m_pcAvatar->m_Location ) );
  1704. cMasterServer::ServerMessage( ColorGreen,this,(char *)szPacketCast);
  1705. #endif
  1706. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, m_pcAvatar->TurnToTarget(flTargetHeading, pcTargetObject->GetGUID() ), 3 );
  1707. }
  1708. }
  1709. //If a client is found (in which case the target is another player)
  1710. else
  1711. {
  1712. flTargetHeading = cPhysics::GetHeadingTarget(m_pcAvatar->m_Location,pcTargetObj->m_pcAvatar->m_Location);
  1713. cMasterServer::ServerMessage( ColorGreen,this,"Client found.");
  1714. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, m_pcAvatar->TurnToTarget(flTargetHeading, pcTargetObj->m_pcAvatar->GetGUID() ), 3 );
  1715. WORD wTotalOpponentHealth = pcTargetObj->m_pcAvatar->GetTotalHealth();
  1716. //Now perform a very basic combat calculation..no where near accurate.
  1717. DWORD dwDamage = 10;
  1718. DWORD dwDamageType = 0x04;
  1719. double dSeverity = ( double ) wTotalOpponentHealth / dwDamage;
  1720. int iNewHealth;
  1721. BOOL fKilledPlayer = FALSE;
  1722. //Following var(s) only used if there is a kill
  1723. cMessage cmAnim;
  1724. //error here
  1725. cMessage cmBeginMessage = m_pcAvatar->AttackBeginMessage( ++m_dwF7B0Sequence, m_pcAvatar->GetGUID( ) );
  1726. cMessage cmHealthLoss = pcTargetObj->m_pcAvatar->DecrementHealth( dwDamage, iNewHealth );
  1727. if( iNewHealth <= 0 )
  1728. {
  1729. fKilledPlayer = TRUE;
  1730. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, pcTargetObj->m_pcAvatar->ChangeCombatMode( FALSE, 0), 3 );
  1731. cWorldManager::SendToAllInFocus( pcTargetObj->m_pcAvatar->m_Location, pcTargetObj->m_pcAvatar->Animation( 0x11L, 2.0f ), 3 );
  1732. cMasterServer::Corpse( pcTargetObj );
  1733. cWorldManager::SendToAllInFocus( pcTargetObj->m_pcAvatar->m_Location, pcTargetObj->m_pcAvatar->ChangeCombatMode( FALSE, 0), 3 );
  1734. cWorldManager::TeleportAvatar( pcTargetObj, cMasterServer::m_StartingLoc );
  1735. char szDeathNotice[200];
  1736. wsprintf( szDeathNotice, "%s has killed %s", m_pcAvatar->m_strName.c_str(), pcTargetObj->m_pcAvatar->m_strName.c_str( ) );
  1737. pcTargetObj->AddPacket( WORLD_SERVER, pcTargetObj->m_pcAvatar->SetHealth( pcTargetObj->m_pcAvatar->GetTotalHealth( ) ), 4 );
  1738. }
  1739. else
  1740. {
  1741. AddPacket(WORLD_SERVER,m_pcAvatar->CombatAnimation( dwMagTarget ),4);
  1742. pcTargetObj->AddPacket( WORLD_SERVER, pcTargetObj->m_pcAvatar->RecieveDamageMessage( ++pcTargetObj->m_dwF7B0Sequence, m_pcAvatar->m_strName, dwDamageType, dSeverity, dwDamage, 0x7 ), 4 );
  1743. AddPacket( WORLD_SERVER, m_pcAvatar->DoDamageMessage( ++m_dwF7B0Sequence, pcTargetObj->m_pcAvatar->m_strName, dwDamageType, dSeverity, dwDamage), 4 );
  1744. }
  1745. }
  1746. float flUserHeading = cPhysics::GetAvatarHeading( m_pcAvatar->m_Location );
  1747. iTurnTime = cPhysics::GetHeadingDifference( flUserHeading, flTargetHeading ) / 12 + 2;
  1748. }
  1749. else
  1750. {
  1751. iTurnTime = 1;
  1752. dwMagTarget = m_pcAvatar->GetGUID();
  1753. }
  1754. cWarJobParam* WarJobParam = new cWarJobParam( dwSpellID, m_pcAvatar->GetGUID(), dwMagTarget, m_pcAvatar->m_Location, dwSequenceSpell );
  1755. int iJob = cMasterServer::m_pcJobPool->CreateJob( &cAvatar::WarAnimation1, (LPVOID) WarJobParam, NULL, "WarAnimation1", iTurnTime, 1);
  1756. break;
  1757. }
  1758. case CHANGE_COMBAT_MODE: //0x0053
  1759. {
  1760. if ( pbData[12] == 0x02 ) //Enter Melee Mode
  1761. {
  1762. if(!pcW)
  1763. {
  1764. cMessage Anim = m_pcAvatar->ChangeCombatMode( TRUE, 0);
  1765. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, Anim, 3 );
  1766. }
  1767. else if(pcW->m_fEquipped == 0)
  1768. {
  1769. cMessage Anim = m_pcAvatar->ChangeCombatMode( TRUE, 0);
  1770. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, Anim, 3 );
  1771. }
  1772. else
  1773. {
  1774. cMessage Anim = m_pcAvatar->ChangeCombatMode( TRUE, pcW->m_bWieldType);
  1775. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, Anim, 3 );
  1776. }
  1777. }
  1778. else if ( pbData[12] == 0x03 ) //Enter Ranged Combat Mode
  1779. {
  1780. cMessage Anim = m_pcAvatar->ChangeMissileMode( TRUE, 0x02);
  1781. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, Anim, 3 );
  1782. }
  1783. else if ( pbData[12] == 0x04 ) //Enter Spell Mode
  1784. {
  1785. cMessage Anim = m_pcAvatar->ChangeSpellMode( TRUE );
  1786. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, Anim, 3 );
  1787. }
  1788. else if ( pbData[12] == 0x01 ) //Leave combat
  1789. {
  1790. cMessage Anim = m_pcAvatar->ChangeCombatMode( FALSE, 0 );
  1791. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, Anim, 3 );
  1792. cMessage cmCompleteAttackMessage = m_pcAvatar->AttackCompleteMessage( ++m_dwF7B0Sequence );
  1793. AddPacket( WORLD_SERVER, cmCompleteAttackMessage, 4 );
  1794. }
  1795. break;
  1796. }
  1797. case STACK_ITEMS: //0x0054
  1798. {
  1799. break;
  1800. }
  1801. case SPLIT_ITEMS: //0x0055
  1802. {
  1803. //msg format:
  1804. //DWORD Item GUID of original item
  1805. //DWORD Avatar GUID
  1806. //DWORD Pack Slot (this is returned in the F7B0 message)
  1807. //DWORD New stack value
  1808. cObject *findItem = m_pcAvatar->FindInventory(MType3);
  1809. cItemModels *pcModel = cItemModels::FindModel(findItem->GetItemModelID());
  1810. DWORD *pdwData = (DWORD *)pbData;
  1811. DWORD Item_GUID = MType3;
  1812. DWORD Slot = MType4;
  1813. DWORD Value = pbData[24];
  1814. if(pcModel->m_ItemType = 9)
  1815. {
  1816. cPyreals *cash = reinterpret_cast<cPyreals *>(findItem);
  1817. cash->Split(this,Item_GUID,Slot,Value);
  1818. }
  1819. break;
  1820. }
  1821. case SQUELCH: //0x0058
  1822. {
  1823. //msg format:
  1824. //DWORD (0x01) - 1 squelched, 0 unsquelched.
  1825. //DWORD (0x00)
  1826. //STRING - Character name
  1827. //DWORD (0x01)
  1828. break;
  1829. }
  1830. case SQUELCH_ACCOUNT: //0x0059
  1831. {
  1832. //msg format:
  1833. //DWORD (0x01) - 1 squelched, 0 unsquelched.
  1834. //DWORD (0x00)
  1835. //STRING - Character name (align to boundary)
  1836. break;
  1837. }
  1838. case SEND_TELL_NAME: //0x005D:
  1839. { // Direct /tells to unknown avatars.
  1840. // BYTE *bTextLength = &pbData[12], *bNameLength;
  1841. BYTE *bTextLength = &pbData[12], *bNameLength;
  1842. WORD wTextLength = pbData[12];
  1843. char *szMessageText = new char[wTextLength];
  1844. CopyMemory( szMessageText, &pbData[14], wTextLength );
  1845. szMessageText[wTextLength] = '\0';
  1846. bNameLength = bTextLength + 2 + *( ( WORD * )bTextLength) + pcRecvPacket->GetPadding( bTextLength );
  1847. cMasterServer::SendTell( szMessageText, cClient::FindClient( ( char * )&bNameLength[2] ), this );
  1848. //cMasterServer::SendTell( (char *)&bTextLength[2], cClient::FindClient( ( char * )&bNameLength[2] ), this );
  1849. break; //case 0x005D
  1850. }
  1851. case VENDOR_BUY_ITEMS: //0x005F
  1852. {
  1853. DWORD ItemID = *( DWORD * )&pbData[24];
  1854. cNPC *m_NPC = reinterpret_cast<cNPC *>(cWorldManager::FindObject(MType3));
  1855. m_NPC->BuyItem(this, m_NPC->GetGUID(), ItemID);
  1856. cMessage cmActionComplete;
  1857. cmActionComplete << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_pcAvatar->m_dwF7B0Sequence << 0x01C7L << 0L;
  1858. AddPacket( WORLD_SERVER,cmActionComplete,4);
  1859. break;
  1860. }
  1861. case VENDOR_SELL_ITEMS: //0x0060
  1862. {
  1863. break;
  1864. }
  1865. case LIFESTONE_RECALL: //0x0063
  1866. {
  1867. cMessage cmLSAnim = m_pcAvatar->LSAnimate();
  1868. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmLSAnim, 3 );
  1869. cMessage cmLSMessage = m_pcAvatar->LSMessage();
  1870. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location,cmLSMessage, 4 );
  1871. m_pcAvatar->m_dwPingCount = 0;
  1872. m_pcAvatar->m_wLifeStone = 1;
  1873. break;
  1874. }
  1875. //Login
  1876. case CHARACTER_SPAWN: //0x00A1
  1877. {
  1878. cWorldManager::AddClient( this );
  1879. break; // case 0x00A1
  1880. }
  1881. case CREATE_FELLOWSHIP: //0x00A2
  1882. {
  1883. //msg info
  1884. //String Name of Fellow (align to boundary)
  1885. //DWORD (0x01)
  1886. WORD wLength;
  1887. char strFellowName[50];
  1888. CopyMemory( &wLength, &pbData[12], 2 );
  1889. CopyMemory( strFellowName, &pbData[14], wLength );
  1890. strFellowName[wLength] = '\0';
  1891. m_pcAvatar->CreateFellowship( m_dwF7B0Sequence, strFellowName );
  1892. break;
  1893. }
  1894. case DISBAND_FELLOWSHIP: //0x00A3
  1895. {
  1896. m_pcAvatar->DisbandFellowship( );
  1897. break;
  1898. }
  1899. case DISMISS_FELLOW_MEMBER: //0x00A4
  1900. {
  1901. DWORD dwDismissPlayerGUID;
  1902. CopyMemory( &dwDismissPlayerGUID, &pbData[12], 4 );
  1903. m_pcAvatar->FellowshipDismiss( dwDismissPlayerGUID );
  1904. break;
  1905. }
  1906. case RECRUIT_FELLOW_MEMBER: //0x00A5
  1907. {
  1908. DWORD dwRecruitPlayerGUID;
  1909. CopyMemory( &dwRecruitPlayerGUID, &pbData[12], 4 );
  1910. bool canRecruit = false;
  1911. // If the avatar is in a fellowship
  1912. if (m_pcAvatar->inFellow)
  1913. {
  1914. cFellowship* aFellowship = cFellowship::GetFellowshipByID(m_pcAvatar->m_dwFellowshipID);
  1915. if (aFellowship->GetIsOpen() == true || aFellowship->GetLeader() == m_pcAvatar->GetGUID())
  1916. {
  1917. canRecruit = true;
  1918. }
  1919. }
  1920. if (canRecruit)
  1921. {
  1922. // Find the recipient
  1923. cClient *pcRecvClient = cClient::FindClient( dwRecruitPlayerGUID );
  1924. if (pcRecvClient)
  1925. {
  1926. cAvatar *pc_RecvAvatar = pcRecvClient->m_pcAvatar;
  1927. if (pc_RecvAvatar)
  1928. {
  1929. if (pc_RecvAvatar->m_dwFellowshipID != 0)
  1930. { // already in a fellowship
  1931. }
  1932. else
  1933. {
  1934. // Open the recipient avatar's confirmation panel
  1935. pcRecvClient->AddPacket( WORLD_SERVER, pc_RecvAvatar->ConfirmPanelRequest(++m_dwF7B0Sequence,4,cWorldManager::NewConfirmSeq(),m_pcAvatar->Name()), 4 );
  1936. // Add the fellowship request to the pending confirmation queue
  1937. cWorldManager::AddPendingConfirm(cWorldManager::CurrentConfirmSeq(),4,m_pcAvatar->Name(),m_pcAvatar->GetGUID(),pc_RecvAvatar->GetGUID());
  1938. }
  1939. }
  1940. }
  1941. }
  1942. break;
  1943. }
  1944. case FELLOWSHIP_PANEL: //0x00A6
  1945. {
  1946. //No meesage is returned from the server for this message.
  1947. break;
  1948. }
  1949. case WRITE_BOOK: //0x00AB
  1950. {
  1951. //Message format: GUID, Page number(?), String (text written)
  1952. //F7B0:00B5 directly followed this message: format - GUID, 0x0, pagenumber?
  1953. break;
  1954. }
  1955. case UNK: //0x00AC
  1956. {
  1957. //This message appeared before writing to a book.
  1958. //the F7B0:00B6 message came directly after.
  1959. //0x00AC Message format: GUID
  1960. //0x00B6 Message format: GUID, 0x0, pagenumber?
  1961. }
  1962. case READ_BOOK: //0x00AE
  1963. {
  1964. cObject *pcObj = m_pcAvatar->FindInventory( MType3 );
  1965. cBooks *book = reinterpret_cast<cBooks *>(pcObj);
  1966. book->Read(this,MType3,MType4);
  1967. break;
  1968. }
  1969. case INSCRIBE: //0x00BF
  1970. {
  1971. //Format is ItemID, string.
  1972. }
  1973. case ASSESS: //0x00C8
  1974. {
  1975. cObject *pcObj = m_pcAvatar->FindInventory( MType3 );
  1976. cObject *pcTargetObj = cWorldManager::FindObject( MType3 );
  1977. cAvatar *v_Avatar = cWorldManager::FindAvatar( MType3 );
  1978. if( pcObj ) //If the object was found in the avatar's inventory
  1979. {
  1980. pcObj->Assess(this);
  1981. break;
  1982. }
  1983. else if(pcTargetObj) //If the object was found in the world (non-inventory)
  1984. {
  1985. pcTargetObj->Assess(this);
  1986. break;
  1987. }
  1988. else if(v_Avatar) //If the object was another player
  1989. {
  1990. v_Avatar->Assess(this);
  1991. }
  1992. break;
  1993. }
  1994. case GIVE_ITEM: //0x00CD
  1995. {
  1996. #ifdef _DEBUG
  1997. cMasterServer::ServerMessage( ColorYellow,this,"Give item message");
  1998. #endif
  1999. cNPC *m_NPC = reinterpret_cast<cNPC *>(cWorldManager::FindObject(MType3));
  2000. cObject *pcObj = m_pcAvatar->FindInventory(MType4);
  2001. cItemModels *pcQuestItem = cItemModels::FindModel(pcObj->GetItemModelID());
  2002. if(!pcQuestItem)
  2003. break; //bail!!
  2004. //Is the client giving the item to a Town Crier? If so, destroy the item.
  2005. if(m_NPC->GetIsVendor() == 3)
  2006. {
  2007. #ifdef _DEBUG
  2008. cMasterServer::ServerMessage( ColorYellow,this,"Town Crier");
  2009. #endif
  2010. //Town crier will take the item and destroy it!
  2011. m_NPC->GiveItem(this,MType3,MType4);
  2012. cMessage cmActionComplete;
  2013. cmActionComplete << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_pcAvatar->m_dwF7B0Sequence << 0x01C7L << 0L;
  2014. AddPacket( WORLD_SERVER,cmActionComplete,4);
  2015. break;
  2016. }
  2017. //Does the NPC accept the item?
  2018. else if(pcQuestItem->m_dwQuestItemID != m_NPC->m_qitem_id1)
  2019. {
  2020. cMasterServer::ServerMessage(ColorYellow,this,"m_dwQuestItemID = %d, m_qitem_id1 = %d",pcQuestItem->m_dwQuestItemID,m_NPC->m_qitem_id1);
  2021. //NPC does not accept this item.
  2022. cMasterServer::ServerMessage(ColorGreen,this,"%s does not know what to do with that",m_NPC->m_strName.c_str());
  2023. //Remove the item
  2024. m_pcAvatar->DeleteFromInventory(pcObj);
  2025. cMessage cmRemoveItem;
  2026. cmRemoveItem << 0x0024L << pcObj->GetGUID();
  2027. AddPacket(WORLD_SERVER,cmRemoveItem,4);
  2028. //Set Container
  2029. cMessage cmSetContainer;
  2030. cmSetContainer << 0x022DL << ++pcObj->m_bInventorySequence << pcObj->GetGUID() << 2L << m_pcAvatar->GetGUID( );
  2031. AddPacket( WORLD_SERVER, cmSetContainer, 4 );
  2032. m_pcAvatar->AddInventory(pcObj);
  2033. //m_pcAvatar->RemoveInventory(pcObj);
  2034. //If there are no results, refuse the item
  2035. // cMessage cmRefuseItem;
  2036. // cmRefuseItem << 0xF7B0L << m_pcAvatar->GetGUID() << ++m_pcAvatar->m_dwF7B0Sequence << 0x00A0L
  2037. // << MType4 << 0x046AL;
  2038. // AddPacket(WORLD_SERVER,cmRefuseItem,4);
  2039. // m_pcAvatar->DeleteFromInventory(pcObj);
  2040. //Failure to give message.
  2041. // cMessage cmFailToGive;
  2042. // cmFailToGive << 0xF7B0L << m_pcAvatar->GetGUID() << ++m_pcAvatar->m_dwF7B0Sequence << 0x028BL << 0x046AL << m_NPC->m_strName.c_str();
  2043. // AddPacket(WORLD_SERVER,cmFailToGive,4);
  2044. cMessage cmActionComplete;
  2045. cmActionComplete << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_pcAvatar->m_dwF7B0Sequence << 0x01C7L << 0L;
  2046. AddPacket( WORLD_SERVER,cmActionComplete,4);
  2047. break;
  2048. }
  2049. //If the NPC accepts the item
  2050. else
  2051. {
  2052. #ifdef _DEBUG
  2053. cMasterServer::ServerMessage( ColorYellow,this,"Quest NPC");
  2054. #endif
  2055. //continue with give item.
  2056. m_NPC->GiveItem(this,MType3,MType4);
  2057. cMessage cmActionComplete;
  2058. cmActionComplete << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_pcAvatar->m_dwF7B0Sequence << 0x01C7L << 0L;
  2059. AddPacket( WORLD_SERVER,cmActionComplete,4);
  2060. break;
  2061. }
  2062. break;
  2063. }
  2064. case REMOVE_PRIVS: //0x00D3
  2065. {
  2066. break;
  2067. }
  2068. case TELE_TO_LB: //0x00D6
  2069. {
  2070. break;
  2071. }
  2072. case REPORT_ABUSE: //0x0140
  2073. {
  2074. break;
  2075. }
  2076. case SEND_TELL_MASK: //0x0147
  2077. {
  2078. break;
  2079. }
  2080. case CLOSE_CONTAINER_FORCED://0x0195
  2081. {
  2082. break;
  2083. }
  2084. case MAKE_SHORTCUT: //0x019C
  2085. {
  2086. break;
  2087. }
  2088. case REMOVE_SHORTCUT: //0x019D
  2089. {
  2090. break;
  2091. }
  2092. case ADJUST_SETTINGS: //0x01A1
  2093. {
  2094. /*
  2095. Character Settings:
  2096. 0x00000001 = Automatically Create Shortcuts checkmarked
  2097. 0x00000100 = Display Tooltips checkmarked
  2098. 0x00000800 = Stay in Chat Mode after sending message checkmarked
  2099. 0x00008000 = Vivid Targeting Indicator checkmarked
  2100. 0x00080000 = Accept Corpse-Looting Permissions checkmarked
  2101. 0x00000200 = Attempt to Decieve Other Players checkmarked
  2102. 0x00000040 = Let Other Players Give You Items checkmarked
  2103. 0x00020000 = Ignore All Trade Requests checkmarked
  2104. 0x00000400 = Run as Default Movement checkmarked
  2105. 0x00001000 = Advanced Combat Interface (no Panel) checkmarked
  2106. 0x00002000 = Auto Target checkmarked
  2107. 0x00000002 = Automatically Repeat Attacks checkmarked
  2108. 0x00000080 = Automatically keep combat targets in view checkmarked
  2109. 0x00010000 = Disable Most Weather Effects checkmarked
  2110. 0x02000000 = Disable House Restriction Effects checkmarked
  2111. 0x00000010 = Invert Mouse Look Up/Down checkmarked
  2112. 0x00004000 = Right-click mouselook checkmarked
  2113. 0x00200000 = Stretch UI checkmarked
  2114. 0x00400000 = Show Coordinates Below The Radar checkmarked
  2115. 0x00800000 = Display Spell Durations checkmarked
  2116. 0x01000000 = Play Sounds Only When Active Application checkmarked
  2117. 0x04000000 = Drag item to player opens Secure Trade checkmarked
  2118. 0x08000000 = Show Alliegance Logons checkmarked
  2119. 0x10000000 = Use Charge Attack checkmarked
  2120. Allegiance Settings:
  2121. 0x00000004 = Accept Allegiance Requests uncheckmarked
  2122. Fellowship Settings:
  2123. 0x00000008 = Accept Fellowship Requests uncheckmarked
  2124. 0x00040000 = Share Fellowship Experience checkmarked
  2125. 0x00100000 = Share Fellowship Loot/Treasure checkmarked
  2126. 0x20000000 = Auto-Accept Fellowship Requests checkmarked
  2127. Trade Settings:
  2128. 0x00020000 = Ignore All Trade Requests checkmarked
  2129. */
  2130. cDatabase::SaveCharacterFlags(m_pcAvatar->GetGUID(),MType3);
  2131. m_pcAvatar->m_dwOptions = MType3;
  2132. break;
  2133. }
  2134. case SAVE_LIFESTONE_POS: //0x01A2
  2135. {
  2136. break;
  2137. }
  2138. case DELETE_SPELL_SHORTCUT: //0x01A8
  2139. {
  2140. break;
  2141. }
  2142. case STOP_ATTACK: //0x01B7
  2143. {
  2144. #ifdef _DEBUG
  2145. char szPacket[60];
  2146. sprintf( szPacket, "F7B1 Packet: %08x",MType2);
  2147. cMasterServer::ServerMessage( ColorYellow,this,(char *)szPacket);
  2148. #endif
  2149. break;
  2150. }
  2151. case REQUEST_HEALTH_UPDATE: //0x01BF
  2152. {
  2153. DWORD dwTargetGUID = *( DWORD * )&pbData[12];
  2154. cClient* pcTarget = cClient::FindClient( dwTargetGUID );
  2155. if( !pcTarget )
  2156. {
  2157. cObject* pcTargetObj = cWorldManager::FindObject( dwTargetGUID );
  2158. if( pcTargetObj )
  2159. {
  2160. cMessage cmHealthBar = pcTargetObj->AdjustBar( m_pcAvatar->GetGUID(), ++m_dwF7B0Sequence );
  2161. AddPacket( WORLD_SERVER, cmHealthBar, 4 );
  2162. }
  2163. }
  2164. else
  2165. {
  2166. cMessage cmHealthLoss = pcTarget->m_pcAvatar->AdjustBar( m_pcAvatar->GetGUID(), ++m_dwF7B0Sequence );
  2167. AddPacket( WORLD_SERVER, cmHealthLoss, 4 );
  2168. }
  2169. break;
  2170. }
  2171. case RETRIEVE_AGE: //0x01C2
  2172. {
  2173. break;
  2174. }
  2175. case RETRIEVE_BIRTH: //0x01C4
  2176. {
  2177. break;
  2178. }
  2179. case EMOTE_TEXT: //0x01DF
  2180. {
  2181. break;
  2182. }
  2183. case EMOTE_COMMAND_TEXT: //0x01E1
  2184. {
  2185. break;
  2186. }
  2187. case ADD_SPELL_SHORTCUT: //0x01E3
  2188. {
  2189. DWORD _tabid = *(DWORD*)&pbData[20];
  2190. cDatabase::AddSpellToTab (m_pcAvatar->GetGUID(), MType3, MType4, _tabid);
  2191. break;
  2192. }
  2193. case REMOVE_SPELL_SHORTCUT: //0x01E4
  2194. {
  2195. break;
  2196. }
  2197. case TELEPORT_TO_PLAYER: //0x01E6
  2198. {
  2199. break;
  2200. }
  2201. case PING_SERVER: //0x01E9
  2202. {
  2203. cMessage cmPing;
  2204. cmPing << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_pcAvatar->m_dwF7B0Sequence << 0x01EAL;
  2205. AddPacket( WORLD_SERVER,cmPing,4);
  2206. break;
  2207. }
  2208. case BEGIN_TRADE: //0x01F6
  2209. {
  2210. break;
  2211. }
  2212. case END_TRADE: //0x01F7
  2213. {
  2214. break;
  2215. }
  2216. case ADD_ITEM_TO_TRADE: //0x01F8
  2217. {
  2218. break;
  2219. }
  2220. case ACCEPT_TRADE: //0x01FA
  2221. {
  2222. break;
  2223. }
  2224. case WITHDRAW_OFFER: //0x01FB
  2225. {
  2226. break;
  2227. }
  2228. case CLEAR_TRADE_WINDOW: //0x0204
  2229. {
  2230. break;
  2231. }
  2232. case CONSENT_CLEAR: //0x0216
  2233. {
  2234. break;
  2235. }
  2236. case CONSENT_LIST: //0x0217
  2237. {
  2238. break;
  2239. }
  2240. case CONSENT_REMOVE: //0x0218
  2241. {
  2242. break;
  2243. }
  2244. case PERMIT_ADD: //0x0219
  2245. {
  2246. break;
  2247. }
  2248. case PERMIT_REMOVE: //0x021A
  2249. {
  2250. break;
  2251. }
  2252. case HOUSE_BUY: //0x021C
  2253. {
  2254. //"Congratulations! You now own this dwelling."
  2255. DWORD dwCovenantGUID = MType3;
  2256. int numItems = MType4;
  2257. DWORD dwObjectGUID;
  2258. int objectOffset = 0;
  2259. char szCommand[512];
  2260. RETCODE retcode;
  2261. int index,i;
  2262. BOOLEAN fetchSuccess = false;
  2263. DWORD dwHouseID;
  2264. char OwnerIDBuff[9];
  2265. DWORD OwnerID = NULL;
  2266. DWORD dwMaintenanceCount; //Apartment, Cottage = 1; Villa, Mansion = 2
  2267. DWORD dwMaintainType;
  2268. DWORD dwMaintainRequired;
  2269. DWORD dwMaintainPaid;
  2270. DWORD dwPurchaseCount; //Apartment = 2; Cottage, Villa = 3; Mansion = 6
  2271. DWORD dwBuyType;
  2272. DWORD dwBuyRequired;
  2273. DWORD dwBuyPaid;
  2274. DWORD dwHouseType;
  2275. DWORD dwPurchaseTime;
  2276. char szName[75];
  2277. std::string strPlayerName = "";
  2278. //While there are items being submitted to purchase the dwelling
  2279. for (index = 0; index < numItems; index++)
  2280. {
  2281. CopyMemory( &dwObjectGUID, &pbData[20 + objectOffset], 4 );
  2282. cObject *pcObj = m_pcAvatar->FindInventory( dwObjectGUID );
  2283. objectOffset += 4;
  2284. sprintf( szCommand, "SELECT HouseID,OwnerID FROM houses_covenants WHERE GUID = '%08x';",dwCovenantGUID);
  2285. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2286. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2287. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwHouseID, sizeof( dwHouseID ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2288. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_CHAR, OwnerIDBuff, sizeof( OwnerIDBuff ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2289. retcode = SQLFetch( cDatabase::m_hStmt );
  2290. sscanf(OwnerIDBuff,"%08x",&OwnerID);
  2291. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2292. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2293. cMasterServer::ServerMessage(ColorGreen,this,"HouseID: %d", dwHouseID);
  2294. sprintf( szCommand, "SELECT ItemLinker,Required,Paid FROM houses_purchase WHERE HouseID = %d AND ItemLinker = %d;",dwHouseID,pcObj->GetItemModelID());
  2295. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2296. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2297. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwBuyType, sizeof( dwBuyType ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2298. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwBuyRequired, sizeof( dwBuyRequired ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2299. retcode = SQLBindCol( cDatabase::m_hStmt, 3, SQL_C_ULONG, &dwBuyPaid, sizeof( dwBuyPaid ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2300. if (SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS)
  2301. {
  2302. fetchSuccess = true;
  2303. }
  2304. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2305. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2306. //If there are items required to purchase the dwelling
  2307. if (fetchSuccess)
  2308. {
  2309. sprintf( szCommand, "SELECT Name FROM avatar WHERE AvatarGUID = %08x;",OwnerID);
  2310. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2311. retcode = SQLExecute( cDatabase::m_hStmt );
  2312. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_CHAR, szName, sizeof( szName ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2313. //Return SQL_SUCCESS if there is a player that corresponds to owner of the fetched house
  2314. if (SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS)
  2315. {
  2316. std::string str1 = szName;
  2317. strPlayerName.assign(str1);
  2318. }
  2319. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2320. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  2321. //If the required amount left of the item is more than the amount paid
  2322. if (dwBuyRequired > dwBuyPaid)
  2323. {
  2324. int remainingBuy = 0;
  2325. remainingBuy = dwBuyRequired - dwBuyPaid;
  2326. if (remainingBuy < pcObj->m_dwQuantity)
  2327. {
  2328. dwBuyPaid += remainingBuy;
  2329. pcObj->m_dwQuantity -= remainingBuy;
  2330. } else {
  2331. dwBuyPaid += pcObj->m_dwQuantity;
  2332. pcObj->m_dwQuantity = 0;
  2333. }
  2334. sprintf( szCommand, "UPDATE houses_purchase SET Paid = %d WHERE HouseID = %d AND ItemLinker = %d;",dwBuyPaid,dwHouseID,pcObj->GetItemModelID());
  2335. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2336. retcode = SQLExecute( cDatabase::m_hStmt );
  2337. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2338. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2339. /* F7B0:0x0228 Message */
  2340. cMessage cmMaintenance;
  2341. cmMaintenance << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x0228L;
  2342. sprintf( szCommand, "SELECT COUNT(ID) FROM houses_maintenance WHERE HouseID = %d;",dwHouseID );
  2343. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2344. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2345. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwMaintenanceCount, sizeof( dwMaintenanceCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2346. retcode = SQLFetch( cDatabase::m_hStmt );
  2347. if( retcode == SQL_NO_DATA )
  2348. dwMaintenanceCount = 0;
  2349. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2350. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2351. cmMaintenance << dwMaintenanceCount; // the number of items required to pay the maintenance cost for this dwelling
  2352. //String maintainName;
  2353. //String maintainPluralName;
  2354. sprintf( szCommand, "SELECT ItemLinker,Required,Paid FROM houses_maintenance WHERE HouseID = %d;",dwHouseID );
  2355. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2356. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2357. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwMaintainType, sizeof( dwMaintainType ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2358. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwMaintainRequired, sizeof( dwMaintainRequired ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2359. retcode = SQLBindCol( cDatabase::m_hStmt, 3, SQL_C_ULONG, &dwMaintainPaid, sizeof( dwMaintainPaid ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2360. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i )
  2361. {
  2362. cItemModels *pcModel = cItemModels::FindModel(dwMaintainType);
  2363. std::string strPluralName = pcModel->m_strName.c_str();
  2364. strPluralName.assign(strPluralName);
  2365. cmMaintenance << dwMaintainRequired // quantity required
  2366. << dwMaintainPaid // quantity paid
  2367. << DWORD(pcModel->m_wModel) // item's object type
  2368. << pcModel->m_strName.c_str() // name of this item
  2369. << strPluralName.c_str(); // plural name of this item (if not specified, use <name> followed by 's' or 'es')
  2370. }
  2371. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2372. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  2373. AddPacket( WORLD_SERVER, cmMaintenance, 4 );
  2374. /* F7B0:0x021D Message */
  2375. //Display Dwelling Purchase/Maintenance Panel
  2376. cMessage cmDisplayPanel;
  2377. cmDisplayPanel << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x021DL
  2378. << dwCovenantGUID; // Covenant Crystal's GUID
  2379. DWORD ownerType = 0x00000001; // Self = 0x00000001; Allegiance = 0x00000003
  2380. DWORD levelReq = 0x00000001; // Apartment, Cottage = 0x00000014; Villa = 0x00000023; Mansion = 0x00000032
  2381. DWORD unknown2 = 0xFFFFFFFF;
  2382. DWORD rankReq = 0xFFFFFFFF; // Apartment, Cottage, Villa = 0xFFFFFFFF; Mansion = 0x00000006
  2383. DWORD unknown3 = 0xFFFFFFFF;
  2384. DWORD unknown4 = 0x00000000;
  2385. DWORD unknown5 = 0x00000001;
  2386. DWORD ownerName= 0x00000000;
  2387. DWORD purchaseCount = 0x00000001; // Apartment = 2; Cottage, Villa = 3; Mansion = 6;
  2388. cmDisplayPanel << dwHouseID // Dwelling ID
  2389. << OwnerID // Dwelling Owner ID (NULL == 0x00000000)
  2390. << ownerType
  2391. << levelReq // level requirement to purchase this dwelling (-1 if no requirement)
  2392. << unknown2
  2393. << rankReq // rank requirement to purchase this dwelling (-1 if no requirement)
  2394. << unknown3
  2395. << unknown4
  2396. // << unknown5
  2397. << strPlayerName.c_str(); // name of the current owner (NULL == 0x00000000)
  2398. sprintf( szCommand, "SELECT COUNT(ID) FROM houses_purchase WHERE HouseID = %d;",dwHouseID );
  2399. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2400. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2401. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwPurchaseCount, sizeof( dwPurchaseCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2402. retcode = SQLFetch( cDatabase::m_hStmt );
  2403. if( retcode == SQL_NO_DATA )
  2404. dwPurchaseCount = 0;
  2405. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2406. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2407. cmDisplayPanel << dwPurchaseCount; // the number of items required to purchase this dwelling
  2408. //String buyName;
  2409. //String buyPluralName;
  2410. sprintf( szCommand, "SELECT ItemLinker,Required,Paid FROM houses_purchase WHERE HouseID = %d;",dwHouseID );
  2411. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2412. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2413. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwBuyType, sizeof( dwBuyType ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2414. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwBuyRequired, sizeof( dwBuyRequired ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2415. retcode = SQLBindCol( cDatabase::m_hStmt, 3, SQL_C_ULONG, &dwBuyPaid, sizeof( dwBuyPaid ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2416. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i )
  2417. {
  2418. if( retcode == SQL_NO_DATA )
  2419. {
  2420. dwBuyRequired = 1;
  2421. dwBuyPaid = 0;
  2422. dwBuyType = 12;
  2423. }
  2424. cItemModels *pcModel = cItemModels::FindModel(dwBuyType);
  2425. std::string strPluralName = pcModel->m_strName.c_str();
  2426. strPluralName.assign(strPluralName + "s");
  2427. cmDisplayPanel << dwBuyRequired // quantity required
  2428. << dwBuyPaid // quantity paid
  2429. << DWORD(pcModel->m_wModel) // item's object type
  2430. << pcModel->m_strName.c_str() // name of this item
  2431. << strPluralName.c_str(); // plural name of this item (if not specified, use <name> followed by 's' or 'es')
  2432. }
  2433. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2434. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  2435. sprintf( szCommand, "SELECT COUNT(ID) FROM houses_maintenance WHERE HouseID = %d;",dwHouseID );
  2436. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2437. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2438. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwMaintenanceCount, sizeof( dwMaintenanceCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2439. retcode = SQLFetch( cDatabase::m_hStmt );
  2440. if( retcode == SQL_NO_DATA )
  2441. dwMaintenanceCount = 0;
  2442. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2443. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2444. cmDisplayPanel << dwMaintenanceCount; // the number of items required to pay the maintenance cost for this dwelling
  2445. //String maintainName;
  2446. //String maintainPluralName;
  2447. sprintf( szCommand, "SELECT ItemLinker,Required,Paid FROM houses_maintenance WHERE HouseID = %d;",dwHouseID );
  2448. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2449. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2450. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwMaintainType, sizeof( dwMaintainType ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2451. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwMaintainRequired, sizeof( dwMaintainRequired ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2452. retcode = SQLBindCol( cDatabase::m_hStmt, 3, SQL_C_ULONG, &dwMaintainPaid, sizeof( dwMaintainPaid ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2453. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i )
  2454. {
  2455. if( retcode == SQL_NO_DATA )
  2456. {
  2457. dwMaintainRequired = 1;
  2458. dwMaintainPaid = 0;
  2459. dwMaintainType = 12;
  2460. }
  2461. cItemModels *pcModel = cItemModels::FindModel(dwMaintainType);
  2462. std::string strPluralName = pcModel->m_strName.c_str();
  2463. strPluralName.assign(strPluralName + "s");
  2464. cmDisplayPanel << dwMaintainRequired // quantity required
  2465. << dwMaintainPaid // quantity paid
  2466. << DWORD(pcModel->m_wModel) // item's object type
  2467. << pcModel->m_strName.c_str() // name of this item
  2468. << strPluralName.c_str(); // plural name of this item (if not specified, use <name> followed by 's' or 'es')
  2469. }
  2470. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2471. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  2472. AddPacket(WORLD_SERVER,cmDisplayPanel,4);
  2473. //Alter avatar inventory accordingly
  2474. if (pcObj->m_dwQuantity <= 0)
  2475. {
  2476. //Destroy object
  2477. cMessage cmDestroyObject;
  2478. cmDestroyObject << 0x0024L << dwObjectGUID;
  2479. AddPacket( WORLD_SERVER, cmDestroyObject, 4 );
  2480. m_pcAvatar->RemoveInventory( pcObj );
  2481. } else {
  2482. cMasterServer::ServerMessage(ColorGreen,this,"ItemModelID: %d, ItemQuant: %d",pcObj->GetItemModelID(),pcObj->m_dwQuantity);
  2483. //Adjust stack size
  2484. cMessage cmAdjustStack;
  2485. //cItemModels *pcModel = cItemModels::FindModel( pcObj->m_dwItemModelID );
  2486. cmAdjustStack << 0x0197L
  2487. << BYTE(0x00) //BYTE sequence -- Seems to be a sequence number of some sort
  2488. << DWORD(pcObj->GetGUID( )) //Object item -- Item getting its stack adjusted.
  2489. << DWORD(pcObj->m_dwQuantity) //DWORD count -- New number of items in the stack.
  2490. << DWORD(pcObj->m_dwQuantity);//DWORD (pcObj->m_dwQuantity * pcModel->m_dwValue); //DWORD value -- New value for the item.
  2491. AddPacket( WORLD_SERVER, cmAdjustStack, 4 );
  2492. }
  2493. }
  2494. }
  2495. }
  2496. BOOLEAN purchasePaid = true;
  2497. DWORD dwRequired;
  2498. DWORD dwPaid;
  2499. sprintf( szCommand, "SELECT Required,Paid FROM houses_purchase WHERE HouseID = %d;",dwHouseID );
  2500. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2501. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2502. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwRequired, sizeof( dwBuyRequired ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2503. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwPaid, sizeof( dwBuyPaid ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2504. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i ) {
  2505. if (dwRequired > dwPaid) purchasePaid = false; // determine whether all items are now paid
  2506. }
  2507. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2508. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  2509. if (purchasePaid)
  2510. {
  2511. //Update the database records to record the avatar owning the house
  2512. //Update the covenant crystal
  2513. sprintf( szCommand, "UPDATE houses_covenants SET OwnerID = %d WHERE GUID = '%08x';",m_pcAvatar->GetGUID( ),dwCovenantGUID );
  2514. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2515. retcode = SQLExecute( cDatabase::m_hStmt );
  2516. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2517. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2518. sprintf( szCommand, "SELECT HouseID FROM houses_covenants WHERE GUID = '%08x';",dwCovenantGUID );
  2519. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2520. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2521. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwHouseID, sizeof( dwHouseID ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2522. retcode = SQLFetch( cDatabase::m_hStmt );
  2523. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2524. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2525. //Update the house
  2526. sprintf( szCommand, "UPDATE houses SET OwnerID = %d WHERE wModel = %d;",m_pcAvatar->GetGUID( ),dwHouseID );
  2527. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2528. retcode = SQLExecute( cDatabase::m_hStmt );
  2529. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2530. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2531. cMasterServer::ServerMessage(ColorGreen,this,"Congratulations! You now own this dwelling.");
  2532. sprintf( szCommand, "SELECT HouseID,HouseType,PurchaseTime FROM houses_covenants WHERE GUID = '%08x';",dwCovenantGUID );
  2533. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2534. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2535. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwHouseType, sizeof( dwHouseType ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2536. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwPurchaseTime, sizeof( dwPurchaseTime ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2537. retcode = SQLFetch( cDatabase::m_hStmt );
  2538. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2539. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2540. /* F7B0:0x0225 Message */
  2541. //House Information for Owners
  2542. cMessage cmHouseInfo;
  2543. cmHouseInfo << 0x0225L
  2544. << dwPurchaseTime
  2545. << dwPurchaseTime // maintainence last paid?
  2546. << dwHouseType // Cottage = 1; Villa = 2; Mansion = 3; Apartment = 4
  2547. << DWORD(0x0L); // unknown (0x00000000)
  2548. DWORD dwPurchaseCount; // Apartment = 2; Cottage, Villa = 3; Mansion = 6;
  2549. sprintf( szCommand, "SELECT COUNT(ID) FROM houses_purchase WHERE HouseID = %d;",dwHouseID );
  2550. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2551. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2552. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwPurchaseCount, sizeof( dwPurchaseCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2553. retcode = SQLFetch( cDatabase::m_hStmt );
  2554. if( retcode == SQL_NO_DATA )
  2555. dwPurchaseCount = 0;
  2556. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2557. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2558. cmHouseInfo << dwPurchaseCount;
  2559. DWORD dwBuyType;
  2560. DWORD dwBuyRequired;
  2561. DWORD dwBuyPaid;
  2562. //String buyName;
  2563. //String buyPluralName;
  2564. sprintf( szCommand, "SELECT ItemLinker,Required,Paid FROM houses_purchase WHERE HouseID = %d;",dwHouseID );
  2565. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2566. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2567. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwBuyType, sizeof( dwBuyType ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2568. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwBuyRequired, sizeof( dwBuyRequired ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2569. retcode = SQLBindCol( cDatabase::m_hStmt, 3, SQL_C_ULONG, &dwBuyPaid, sizeof( dwBuyPaid ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2570. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i )
  2571. {
  2572. cItemModels *pcModel = cItemModels::FindModel(dwBuyType);
  2573. std::string strPluralName = pcModel->m_strName.c_str();
  2574. strPluralName.assign(strPluralName);
  2575. cmHouseInfo << dwBuyRequired // quantity required
  2576. << dwBuyPaid // quantity paid
  2577. << DWORD(pcModel->m_wModel) // item's object type
  2578. << pcModel->m_strName.c_str() // name of this item
  2579. << strPluralName.c_str(); // plural name of this item (if not specified, use <name> followed by 's' or 'es')
  2580. }
  2581. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2582. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  2583. DWORD dwMaintenanceCount; // Apartment, Cottage = 1; Villa, Mansion = 2;
  2584. sprintf( szCommand, "SELECT COUNT(ID) FROM houses_maintenance WHERE HouseID = %d;",dwHouseID );
  2585. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2586. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2587. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwMaintenanceCount, sizeof( dwMaintenanceCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2588. retcode = SQLFetch( cDatabase::m_hStmt );
  2589. if( retcode == SQL_NO_DATA )
  2590. dwMaintenanceCount = 0;
  2591. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2592. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2593. cmHouseInfo << dwMaintenanceCount; // the number of items required to pay the maintenance cost for this dwelling
  2594. DWORD dwMaintainType;
  2595. DWORD dwMaintainRequired;
  2596. DWORD dwMaintainPaid;
  2597. //String maintainName;
  2598. //String maintainPluralName;
  2599. sprintf( szCommand, "SELECT ItemLinker,Required,Paid FROM houses_maintenance WHERE HouseID = %d;",dwHouseID );
  2600. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2601. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2602. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwMaintainType, sizeof( dwMaintainType ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2603. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwMaintainRequired, sizeof( dwMaintainRequired ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2604. retcode = SQLBindCol( cDatabase::m_hStmt, 3, SQL_C_ULONG, &dwMaintainPaid, sizeof( dwMaintainPaid ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2605. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i )
  2606. {
  2607. cItemModels *pcModel = cItemModels::FindModel(dwMaintainType);
  2608. std::string strPluralName = pcModel->m_strName.c_str();
  2609. strPluralName.assign(strPluralName);
  2610. cmHouseInfo << dwMaintainRequired // quantity required
  2611. << dwMaintainPaid // quantity paid
  2612. << DWORD(pcModel->m_wModel) // item's object type
  2613. << pcModel->m_strName.c_str() // name of this item
  2614. << strPluralName.c_str(); // plural name of this item (if not specified, use <name> followed by 's' or 'es')
  2615. }
  2616. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2617. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  2618. char locBuff[9];
  2619. cLocation locCovenant;
  2620. sprintf( szCommand, "SELECT Landblock,Position_X,Position_Y,Position_Z,Orientation_W,Orientation_X,Orientation_Y,Orientation_Z FROM houses_covenants WHERE HouseID = %d;",dwHouseID );
  2621. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2622. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2623. int iCol = 1;
  2624. retcode = SQLBindCol( cDatabase::m_hStmt, iCol++, SQL_C_CHAR, locBuff, sizeof( locBuff ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2625. retcode = SQLBindCol( cDatabase::m_hStmt, iCol++, SQL_C_FLOAT, &locCovenant.m_flX, sizeof( &locCovenant.m_flX ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2626. retcode = SQLBindCol( cDatabase::m_hStmt, iCol++, SQL_C_FLOAT, &locCovenant.m_flY, sizeof( &locCovenant.m_flY ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2627. retcode = SQLBindCol( cDatabase::m_hStmt, iCol++, SQL_C_FLOAT, &locCovenant.m_flZ, sizeof( &locCovenant.m_flZ ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2628. retcode = SQLBindCol( cDatabase::m_hStmt, iCol++, SQL_C_FLOAT, &locCovenant.m_flA, sizeof( &locCovenant.m_flA ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2629. retcode = SQLBindCol( cDatabase::m_hStmt, iCol++, SQL_C_FLOAT, &locCovenant.m_flB, sizeof( &locCovenant.m_flB ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2630. retcode = SQLBindCol( cDatabase::m_hStmt, iCol++, SQL_C_FLOAT, &locCovenant.m_flC, sizeof( &locCovenant.m_flC ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2631. retcode = SQLBindCol( cDatabase::m_hStmt, iCol++, SQL_C_FLOAT, &locCovenant.m_flW, sizeof( &locCovenant.m_flW ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2632. if (SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS)
  2633. {
  2634. sscanf(locBuff,"%08x",&locCovenant.m_dwLandBlock);
  2635. }
  2636. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2637. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  2638. cmHouseInfo << locCovenant;
  2639. }
  2640. break;
  2641. }
  2642. case HOUSE_MAINTAIN: //0x0221
  2643. {
  2644. //"Maintenance partially paid."
  2645. //"Maintenance paid."
  2646. //"The rent has already been paid!"
  2647. DWORD dwCovenantGUID = MType3;
  2648. int numItems = MType4;
  2649. DWORD dwObjectGUID;
  2650. int objectOffset = 0;
  2651. char szCommand[512];
  2652. RETCODE retcode;
  2653. int index,i;
  2654. BOOLEAN fetchSuccess = false;
  2655. DWORD dwHouseID;
  2656. char OwnerIDBuff[9];
  2657. DWORD OwnerID = NULL;
  2658. DWORD dwMaintenanceCount; //Apartment, Cottage = 1; Villa, Mansion = 2
  2659. DWORD dwMaintainType;
  2660. DWORD dwMaintainRequired;
  2661. DWORD dwMaintainPaid;
  2662. DWORD dwPurchaseCount; //Apartment = 2; Cottage, Villa = 3; Mansion = 6
  2663. DWORD dwBuyType;
  2664. DWORD dwBuyRequired;
  2665. DWORD dwBuyPaid;
  2666. char szName[75];
  2667. std::string strPlayerName = "";
  2668. //While there are items being submitted to maintain the dwelling
  2669. for (index = 0; index < numItems; index++)
  2670. {
  2671. CopyMemory( &dwObjectGUID, &pbData[20 + objectOffset], 4 );
  2672. cObject *pcObj = m_pcAvatar->FindInventory( dwObjectGUID );
  2673. objectOffset += 4;
  2674. sprintf( szCommand, "SELECT HouseID,OwnerID FROM houses_covenants WHERE GUID = '%08x';",dwCovenantGUID);
  2675. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2676. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2677. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwHouseID, sizeof( dwHouseID ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2678. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_CHAR, OwnerIDBuff, sizeof( OwnerIDBuff ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2679. retcode = SQLFetch( cDatabase::m_hStmt );
  2680. sscanf(OwnerIDBuff,"%08x",&OwnerID);
  2681. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2682. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2683. cMasterServer::ServerMessage(ColorGreen,this,"HouseID: %d", dwHouseID);
  2684. sprintf( szCommand, "SELECT ItemLinker,Required,Paid FROM houses_maintenance WHERE HouseID = %d AND ItemLinker = %d;",dwHouseID,pcObj->GetItemModelID());
  2685. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2686. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2687. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwMaintainType, sizeof( dwMaintainType ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2688. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwMaintainRequired, sizeof( dwMaintainRequired ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2689. retcode = SQLBindCol( cDatabase::m_hStmt, 3, SQL_C_ULONG, &dwMaintainPaid, sizeof( dwMaintainPaid ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2690. if (SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS)
  2691. {
  2692. fetchSuccess = true;
  2693. cMasterServer::ServerMessage(ColorGreen,this,"dwcovenantGUID: %08x, ObjectGUID: %d, ItemLinker: %d, ItemModelID: %d, ItemQuant: %d",dwCovenantGUID,dwObjectGUID,dwMaintainType,pcObj->GetItemModelID(),pcObj->m_dwQuantity);
  2694. }
  2695. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2696. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2697. //If there are items required to maintain the dwelling
  2698. if (fetchSuccess)
  2699. {
  2700. sprintf( szCommand, "SELECT Name FROM avatar WHERE AvatarGUID = %08x;",OwnerID);
  2701. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2702. retcode = SQLExecute( cDatabase::m_hStmt );
  2703. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_CHAR, szName, sizeof( szName ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2704. //Return SQL_SUCCESS if there is a player that corresponds to owner of the fetched house
  2705. if (SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS)
  2706. {
  2707. std::string str1 = szName;
  2708. strPlayerName.assign(str1);
  2709. }
  2710. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2711. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  2712. if (dwMaintainRequired > dwMaintainPaid)
  2713. {
  2714. int remainingMaintenance = 0;
  2715. remainingMaintenance = dwMaintainRequired - dwMaintainPaid;
  2716. if (remainingMaintenance < pcObj->m_dwQuantity)
  2717. {
  2718. dwMaintainPaid += remainingMaintenance;
  2719. pcObj->m_dwQuantity -= remainingMaintenance;
  2720. } else {
  2721. dwMaintainPaid += pcObj->m_dwQuantity;
  2722. pcObj->m_dwQuantity = 0;
  2723. }
  2724. sprintf( szCommand, "UPDATE houses_maintenance SET Paid = %d WHERE HouseID = %d AND ItemLinker = %d;",dwMaintainPaid,dwHouseID,pcObj->GetItemModelID());
  2725. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2726. retcode = SQLExecute( cDatabase::m_hStmt );
  2727. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2728. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2729. /* F7B0:0x0228 Message */
  2730. cMessage cmMaintenance;
  2731. cmMaintenance << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x0228L;
  2732. sprintf( szCommand, "SELECT COUNT(ID) FROM houses_maintenance WHERE HouseID = %d;",dwHouseID );
  2733. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2734. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2735. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwMaintenanceCount, sizeof( dwMaintenanceCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2736. retcode = SQLFetch( cDatabase::m_hStmt );
  2737. if( retcode == SQL_NO_DATA )
  2738. dwMaintenanceCount = 0;
  2739. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2740. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2741. cmMaintenance << dwMaintenanceCount; // the number of items required to pay the maintenance cost for this dwelling
  2742. //String maintainName;
  2743. //String maintainPluralName;
  2744. sprintf( szCommand, "SELECT ItemLinker,Required,Paid FROM houses_maintenance WHERE HouseID = %d;",dwHouseID );
  2745. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2746. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2747. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwMaintainType, sizeof( dwMaintainType ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2748. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwMaintainRequired, sizeof( dwMaintainRequired ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2749. retcode = SQLBindCol( cDatabase::m_hStmt, 3, SQL_C_ULONG, &dwMaintainPaid, sizeof( dwMaintainPaid ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2750. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i )
  2751. {
  2752. cItemModels *pcModel = cItemModels::FindModel(dwMaintainType);
  2753. std::string strPluralName = pcModel->m_strName.c_str();
  2754. strPluralName.assign(strPluralName);
  2755. cmMaintenance << dwMaintainRequired // quantity required
  2756. << dwMaintainPaid // quantity paid
  2757. << DWORD(pcModel->m_wModel) // item's object type
  2758. << pcModel->m_strName.c_str() // name of this item
  2759. << strPluralName.c_str(); // plural name of this item (if not specified, use <name> followed by 's' or 'es')
  2760. }
  2761. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2762. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  2763. AddPacket( WORLD_SERVER, cmMaintenance, 4 );
  2764. /* F7B0:0x021D Message */
  2765. cMessage cmDisplayPanel;
  2766. cmDisplayPanel << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x021DL
  2767. << dwCovenantGUID; // Covenant Crystal's GUID
  2768. DWORD ownerType = 0x00000001; // Self = 0x00000001; Allegiance = 0x00000003
  2769. DWORD levelReq = 0x00000001; // Apartment, Cottage = 0x00000014; Villa = 0x00000023; Mansion = 0x00000032
  2770. DWORD unknown2 = 0xFFFFFFFF;
  2771. DWORD rankReq = 0xFFFFFFFF; // Apartment, Cottage, Villa = 0xFFFFFFFF; Mansion = 0x00000006
  2772. DWORD unknown3 = 0xFFFFFFFF;
  2773. DWORD unknown4 = 0x00000000;
  2774. DWORD unknown5 = 0x00000001;
  2775. DWORD ownerName= 0x00000000;
  2776. DWORD purchaseCount = 0x00000001; // Apartment = 2; Cottage, Villa = 3; Mansion = 6;
  2777. cmDisplayPanel << dwHouseID // Dwelling ID
  2778. << OwnerID // Dwelling Owner ID (NULL == 0x00000000)
  2779. << ownerType
  2780. << levelReq // level requirement to purchase this dwelling (-1 if no requirement)
  2781. << unknown2
  2782. << rankReq // rank requirement to purchase this dwelling (-1 if no requirement)
  2783. << unknown3
  2784. << unknown4
  2785. // << unknown5
  2786. << strPlayerName.c_str(); // name of the current owner (NULL == 0x00000000)
  2787. sprintf( szCommand, "SELECT COUNT(ID) FROM houses_purchase WHERE HouseID = %d;",dwHouseID );
  2788. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2789. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2790. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwPurchaseCount, sizeof( dwPurchaseCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2791. retcode = SQLFetch( cDatabase::m_hStmt );
  2792. if( retcode == SQL_NO_DATA )
  2793. dwPurchaseCount = 0;
  2794. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2795. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2796. cmDisplayPanel << dwPurchaseCount; // the number of items required to purchase this dwelling
  2797. //String buyName;
  2798. //String buyPluralName;
  2799. sprintf( szCommand, "SELECT ItemLinker,Required,Paid FROM houses_purchase WHERE HouseID = %d;",dwHouseID );
  2800. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2801. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2802. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwBuyType, sizeof( dwBuyType ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2803. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwBuyRequired, sizeof( dwBuyRequired ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2804. retcode = SQLBindCol( cDatabase::m_hStmt, 3, SQL_C_ULONG, &dwBuyPaid, sizeof( dwBuyPaid ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2805. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i )
  2806. {
  2807. if( retcode == SQL_NO_DATA )
  2808. {
  2809. dwBuyRequired = 1;
  2810. dwBuyPaid = 0;
  2811. dwBuyType = 12;
  2812. }
  2813. cItemModels *pcModel = cItemModels::FindModel(dwBuyType);
  2814. std::string strPluralName = pcModel->m_strName.c_str();
  2815. strPluralName.assign(strPluralName + "s");
  2816. cmDisplayPanel << dwBuyRequired // quantity required
  2817. << dwBuyPaid // quantity paid
  2818. << DWORD(pcModel->m_wModel) // item's object type
  2819. << pcModel->m_strName.c_str() // name of this item
  2820. << strPluralName.c_str(); // plural name of this item (if not specified, use <name> followed by 's' or 'es')
  2821. }
  2822. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2823. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  2824. sprintf( szCommand, "SELECT COUNT(ID) FROM houses_maintenance WHERE HouseID = %d;",dwHouseID );
  2825. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2826. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2827. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwMaintenanceCount, sizeof( dwMaintenanceCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2828. retcode = SQLFetch( cDatabase::m_hStmt );
  2829. if( retcode == SQL_NO_DATA )
  2830. dwMaintenanceCount = 0;
  2831. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2832. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  2833. cmDisplayPanel << dwMaintenanceCount; // the number of items required to pay the maintenance cost for this dwelling
  2834. //String maintainName;
  2835. //String maintainPluralName;
  2836. sprintf( szCommand, "SELECT ItemLinker,Required,Paid FROM houses_maintenance WHERE HouseID = %d;",dwHouseID );
  2837. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2838. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2839. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwMaintainType, sizeof( dwMaintainType ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  2840. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwMaintainRequired, sizeof( dwMaintainRequired ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2841. retcode = SQLBindCol( cDatabase::m_hStmt, 3, SQL_C_ULONG, &dwMaintainPaid, sizeof( dwMaintainPaid ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2842. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i )
  2843. {
  2844. if( retcode == SQL_NO_DATA )
  2845. {
  2846. dwMaintainRequired = 1;
  2847. dwMaintainPaid = 0;
  2848. dwMaintainType = 12;
  2849. }
  2850. cItemModels *pcModel = cItemModels::FindModel(dwMaintainType);
  2851. std::string strPluralName = pcModel->m_strName.c_str();
  2852. strPluralName.assign(strPluralName + "s");
  2853. cmDisplayPanel << dwMaintainRequired // quantity required
  2854. << dwMaintainPaid // quantity paid
  2855. << DWORD(pcModel->m_wModel) // item's object type
  2856. << pcModel->m_strName.c_str() // name of this item
  2857. << strPluralName.c_str(); // plural name of this item (if not specified, use <name> followed by 's' or 'es')
  2858. }
  2859. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2860. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  2861. AddPacket(WORLD_SERVER,cmDisplayPanel,4);
  2862. //Alter avatar inventory accordingly
  2863. if (pcObj->m_dwQuantity <= 0)
  2864. {
  2865. // Destroy object
  2866. cMessage cmDestroyObject;
  2867. cmDestroyObject << 0x0024L << dwObjectGUID;
  2868. AddPacket( WORLD_SERVER, cmDestroyObject, 4 );
  2869. m_pcAvatar->RemoveInventory( pcObj );
  2870. } else {
  2871. cMasterServer::ServerMessage(ColorGreen,this,"ItemModelID: %d, ItemQuant: %d",pcObj->GetItemModelID(),pcObj->m_dwQuantity);
  2872. //Adjust stack size
  2873. cMessage cmAdjustStack;
  2874. //cItemModels *pcModel = cItemModels::FindModel( pcObj->m_dwItemModelID );
  2875. cmAdjustStack << 0x0197L
  2876. << BYTE(0x00) //BYTE sequence -- Seems to be a sequence number of some sort
  2877. << DWORD(pcObj->GetGUID( )) //Object item -- Item getting its stack adjusted.
  2878. << DWORD(pcObj->m_dwQuantity) //DWORD count -- New number of items in the stack.
  2879. << DWORD(pcObj->m_dwQuantity); //DWORD (pcObj->m_dwQuantity * pcModel->m_dwValue); //DWORD value -- New value for the item.
  2880. AddPacket( WORLD_SERVER, cmAdjustStack, 4 );
  2881. }
  2882. }
  2883. }
  2884. }
  2885. BOOLEAN maintenancePaid = true;
  2886. DWORD dwRequired;
  2887. DWORD dwPaid;
  2888. sprintf( szCommand, "SELECT Required,Paid FROM houses_maintenance WHERE HouseID = %d;",dwHouseID );
  2889. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2890. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  2891. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwRequired, sizeof( dwBuyRequired ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2892. retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_ULONG, &dwPaid, sizeof( dwBuyPaid ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2893. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i )
  2894. {
  2895. if (dwRequired > dwPaid) maintenancePaid = false; // determine whether all items are now paid
  2896. }
  2897. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  2898. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  2899. if (maintenancePaid)
  2900. {
  2901. cMasterServer::ServerMessage(ColorGreen,this,"Maintenance paid.");
  2902. } else {
  2903. cMasterServer::ServerMessage(ColorGreen,this,"Maintenance partially paid.");
  2904. }
  2905. break;
  2906. }
  2907. case HOUSE_ABANDON: //0x021F
  2908. {
  2909. //"You abandon your house!"
  2910. AddPacket( WORLD_SERVER, m_pcAvatar->HouseAbandon( ++m_dwF7B0Sequence ), 4 );
  2911. break;
  2912. }
  2913. case HOUSE_GUEST_ADD: //0x0245
  2914. {
  2915. WORD wLength;
  2916. char strGuestName[50];
  2917. CopyMemory( &wLength, &pbData[12], 2 );
  2918. CopyMemory( strGuestName, &pbData[14], wLength );
  2919. strGuestName[wLength] = '\0';
  2920. /*
  2921. //Reverse bits
  2922. int i,j, c;
  2923. for (i = 0, j = strlen(strName)-1; i<j; i++, j--) {
  2924. c = strGuestName[i];
  2925. strGuestName[i] = strGuestName[j];
  2926. strGuestName[j] = c;
  2927. }
  2928. wLength = atoi(strGuestName);
  2929. */
  2930. m_pcAvatar->HouseGuestAdd(strGuestName);
  2931. break;
  2932. }
  2933. case HOUSE_GUEST_REM_NAME: //0x0246 // by name
  2934. {
  2935. WORD wLength;
  2936. char strGuestName[50];
  2937. CopyMemory( &wLength, &pbData[12], 2 );
  2938. CopyMemory( strGuestName, &pbData[14], wLength );
  2939. strGuestName[wLength] = '\0';
  2940. m_pcAvatar->HouseGuestRemoveName(strGuestName);
  2941. break;
  2942. }
  2943. case HOUSE_OPEN_CLOSE: //0x0247 //Open or Close
  2944. {
  2945. m_pcAvatar->HouseOpenClose( MType3 );
  2946. break;
  2947. }
  2948. case HOUSE_STORAGE: //0x0249 //Add or Remove by Name
  2949. {
  2950. WORD wLength;
  2951. char strGuestName[50];
  2952. DWORD dwStorageSet;
  2953. CopyMemory( &wLength, &pbData[12], 2 );
  2954. CopyMemory( strGuestName, &pbData[14], wLength );
  2955. strGuestName[wLength] = '\0';
  2956. while ((wLength % 2 != 0) || (wLength % 4 == 0)) { wLength++; } //account for string padding
  2957. CopyMemory( &dwStorageSet, &pbData[14+wLength], 4 );
  2958. m_pcAvatar->HouseStorage(strGuestName,dwStorageSet);
  2959. break;
  2960. }
  2961. case HOUSE_BOOT_NAME: //0x024A //Boot by Name
  2962. {
  2963. WORD wLength;
  2964. char strGuestName[50];
  2965. CopyMemory( &wLength, &pbData[12], 2 );
  2966. CopyMemory( strGuestName, &pbData[14], wLength );
  2967. strGuestName[wLength] = '\0';
  2968. m_pcAvatar->HouseBootName(strGuestName);
  2969. break;
  2970. }
  2971. case HOUSE_STORE_REM_ALL: //0x024C //Remove all from storage
  2972. {
  2973. m_pcAvatar->HouseStorageRemoveAll( );
  2974. break;
  2975. }
  2976. case HOUSE_GUEST_LIST: //0x024D
  2977. {
  2978. if (m_pcAvatar->m_wHouseID)
  2979. {
  2980. AddPacket (WORLD_SERVER, m_pcAvatar->HouseGuestList( ++m_dwF7B0Sequence ), 4);
  2981. }
  2982. break;
  2983. }
  2984. case SET_SPEAKER: //0x0251
  2985. {
  2986. break;
  2987. }
  2988. case SHOW_SPEAKER: //0x0252
  2989. {
  2990. break;
  2991. }
  2992. case CLEAR_SPEAKER: //0x0253
  2993. {
  2994. break;
  2995. }
  2996. case SET_MOTD: //0x0254
  2997. {
  2998. break;
  2999. }
  3000. case SHOW_MOTD: //0x0255
  3001. {
  3002. break;
  3003. }
  3004. case CLEAR_MOTD: //0x0256
  3005. {
  3006. break;
  3007. }
  3008. case HOUSE_GUEST_REM_ALL: //0x025E
  3009. {
  3010. char szCommand[512];
  3011. RETCODE retcode;
  3012. char szPacket[60];
  3013. if (m_pcAvatar->m_wHouseID)
  3014. {
  3015. sprintf( szCommand, "DELETE FROM houses_guest_lists WHERE HouseID = %d;",m_pcAvatar->m_wHouseID );
  3016. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3017. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3018. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_CLOSE ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3019. sprintf (szPacket, "You have removed all the guests from your house.");
  3020. cMasterServer::ServerMessage(ColorGreen,this,(char *)szPacket);
  3021. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  3022. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  3023. }
  3024. break;
  3025. }
  3026. case HOUSE_BOOT_ALL: //0x025F
  3027. {
  3028. break;
  3029. }
  3030. case HOUSE_RECALL: //0x0262
  3031. {
  3032. //If the client owns a house
  3033. if (m_pcAvatar->m_wHouseID)
  3034. {
  3035. cMessage cmHRAnim = m_pcAvatar->HRAnimate(); //The House Recall animation
  3036. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmHRAnim, 3 );
  3037. cMessage cmHRMessage = m_pcAvatar->HRMessage(); //The House Recall message
  3038. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location,cmHRMessage, 4 );
  3039. m_pcAvatar->m_dwPingCount = 0;
  3040. m_pcAvatar->m_wHouseRecall = 1;
  3041. }
  3042. break;
  3043. }
  3044. case GET_OBJECT_MANA: //0x0263 //Buggy...
  3045. {
  3046. DWORD dwObjectGUID = *( DWORD * )&pbData[12];
  3047. if ( !dwObjectGUID )
  3048. break;
  3049. cObject *pcObj = m_pcAvatar->FindInventory( dwObjectGUID );
  3050. if( !pcObj )
  3051. if( !( pcObj = cWorldManager::FindObject( dwObjectGUID ) ) )
  3052. break;
  3053. cMessage cmUpdateMana;
  3054. cmUpdateMana << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence << 0x0264L << dwObjectGUID << 0L << 0L;
  3055. AddPacket( WORLD_SERVER, cmUpdateMana, 4 );
  3056. break;
  3057. }
  3058. case HOUSE_HOOKS: //0x0266 //On or Off
  3059. {
  3060. char szCommand[512];
  3061. RETCODE retcode;
  3062. char HookIDBuff[9];
  3063. DWORD HookID;
  3064. WORD wHasItem = 0;
  3065. //If the client owns a house
  3066. if (m_pcAvatar->m_wHouseID)
  3067. {
  3068. if (MType3 == 1)
  3069. {
  3070. sprintf( szCommand, "UPDATE houses_covenants SET HooksOn = %d WHERE HouseID = %d;",1,m_pcAvatar->m_wHouseID );
  3071. } else {
  3072. sprintf( szCommand, "UPDATE houses_covenants SET HooksOn = %d WHERE HouseID = %d;",0,m_pcAvatar->m_wHouseID );
  3073. }
  3074. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3075. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3076. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_CLOSE ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3077. sprintf( szCommand, "SELECT GUID,HasItem FROM houses_hooks WHERE HouseID = %d;",m_pcAvatar->m_wHouseID );
  3078. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3079. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3080. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_CHAR, HookIDBuff, sizeof( HookIDBuff ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  3081. for ( int i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i )
  3082. {
  3083. if (wHasItem != 1)
  3084. {
  3085. sscanf(HookIDBuff,"%08x",&HookID);
  3086. cMessage cmHookVisible;
  3087. cmHookVisible << 0xF74B
  3088. << HookID;
  3089. if (MType3 == 1) {
  3090. cmHookVisible << WORD(0x0014);
  3091. } else {
  3092. cmHookVisible << WORD(0x0034);
  3093. }
  3094. cmHookVisible << WORD(0x0000)
  3095. << WORD(m_pcAvatar->m_wNumLogins)
  3096. << WORD(m_pcAvatar->m_wPortalCount++);
  3097. AddPacket( WORLD_SERVER, cmHookVisible, 4 );
  3098. cMessage cmHookBoolean;
  3099. cmHookBoolean << 0x02D2L //Set Object Boolean
  3100. << BYTE(0x04) //BYTE sequence
  3101. << HookID //Hook GUID
  3102. << DWORD(0x18L);//Hook Visibility
  3103. //Boolean value - Boolean property value (0 = False, 1 = True)
  3104. if (MType3 == 1) {
  3105. cmHookBoolean << DWORD(0x0L);
  3106. } else {
  3107. cmHookBoolean << DWORD(0x1L);
  3108. }
  3109. AddPacket( WORLD_SERVER, cmHookBoolean, 4 );
  3110. }
  3111. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  3112. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  3113. }
  3114. }
  3115. break;
  3116. }
  3117. case HOUSE_GUEST_ALLEG: //0x0267 // Add or Remove
  3118. {
  3119. //"You have granted your monarchy access to your dwelling."
  3120. //"The monarchy already has access to your dwelling."
  3121. //"You have revoked access to your dwelling to your monarchy."
  3122. //"The monarchy did not have access to your dwelling."
  3123. //"You must be part of an allegiance to use this command."
  3124. break;
  3125. }
  3126. case JOIN_CHESS_GAME: //0x0269
  3127. {
  3128. break;
  3129. }
  3130. case LEAVE_CHESS_GAME: //0x026A
  3131. {
  3132. break;
  3133. }
  3134. case MOVE_CHESS_PIECE: //0x026B
  3135. {
  3136. break;
  3137. }
  3138. case OFFER_CHESS_DRAW: //0x026E
  3139. {
  3140. break;
  3141. }
  3142. case HOUSE_AVAIL: //0x0270
  3143. {
  3144. char szCommand[512];
  3145. RETCODE retcode;
  3146. DWORD dwCottageCount, dwVillaCount, dwMansionCount, dwApartmentCount;
  3147. dwCottageCount = dwVillaCount = dwMansionCount = dwApartmentCount = 0;
  3148. char dwLandblockBuff[9];
  3149. DWORD dwLandblock;
  3150. int i;
  3151. cMessage cmHouseAvail;
  3152. cmHouseAvail << 0xF7B0L << m_pcAvatar->GetGUID( ) << ++m_dwF7B0Sequence
  3153. << 0x0271L;
  3154. //Determine cottage availability
  3155. sprintf( szCommand, "SELECT COUNT(ID) FROM houses_covenants WHERE HouseType=1 AND OwnerID = %d;",0 );
  3156. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3157. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3158. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwCottageCount, sizeof( dwCottageCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3159. retcode = SQLFetch( cDatabase::m_hStmt );
  3160. if( retcode == SQL_NO_DATA )
  3161. dwCottageCount = 0;
  3162. /*
  3163. if (dwCovenantCount != 1)
  3164. {
  3165. sprintf (szPacket, "There are %d cottages available.",dwCovenantCount);
  3166. } else {
  3167. sprintf (szPacket, "There is 1 cottage available.");
  3168. }
  3169. cMasterServer::ServerMessage(ColorGreen,this,(char *)szPacket);
  3170. */
  3171. cmHouseAvail << dwCottageCount;
  3172. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  3173. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  3174. //sprintf( szCommand, "SELECT Landblock, Position_X, Position_Y FROM houses_covenants WHERE HouseType=1 AND OwnerID IS NULL;" );
  3175. sprintf( szCommand, "SELECT Landblock FROM houses_covenants WHERE HouseType=1 AND OwnerID = %d;",0 );
  3176. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  3177. retcode = SQLExecute( cDatabase::m_hStmt );
  3178. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_CHAR, dwLandblockBuff, sizeof( dwLandblockBuff ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  3179. //retcode = SQLBindCol( cDatabase::m_hStmt, 2, SQL_C_FLOAT, &flX, sizeof( float ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  3180. //retcode = SQLBindCol( cDatabase::m_hStmt, 3, SQL_C_FLOAT, &flY, sizeof( float ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  3181. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i )
  3182. {
  3183. sscanf(dwLandblockBuff,"%08x",&dwLandblock);
  3184. /*
  3185. float lat, lng;
  3186. //lat = ((((dwLandblock >> 16) & 0xFF) - 0x7F) * 192 + flY - 84) / 240;
  3187. //lng = ((((dwLandblock >> 24) & 0xFF) - 0x7F) * 192 + flX - 84) / 240;
  3188. lat = ((((((dwLandblock & 0x00FF0000) / 0x0010000) & 0xFF) + 1) * 8) + static_cast<float>(flY / 24) - 1027.5) / 10;
  3189. lng = ((((((dwLandblock & 0xFF000000) / 0x1000000) & 0xFF) + 1) * 8) + static_cast<float>(flX / 24) - 1027.5) / 10;
  3190. char ns[10];
  3191. char ew[10];
  3192. if (lat > 0) { sprintf (ns, "%.2fN",lat); }
  3193. else { sprintf (ns, "%.2fS",fabs(lat)); }
  3194. if (lng > 0) {sprintf (ew, "%.2fE",lng); }
  3195. else { sprintf (ew, "%.2fW",fabs(lng)); }
  3196. sprintf (szPacket, "%s%s, %s",indent,ns,ew);
  3197. cMasterServer::ServerMessage(ColorGreen,this,(char *)szPacket);
  3198. */
  3199. cmHouseAvail << dwLandblock;
  3200. }
  3201. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  3202. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  3203. //Determine villa availability
  3204. sprintf( szCommand, "SELECT COUNT(ID) FROM houses_covenants WHERE HouseType=2 AND OwnerID = %d;",0 );
  3205. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3206. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3207. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwVillaCount, sizeof( dwVillaCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3208. retcode = SQLFetch( cDatabase::m_hStmt );
  3209. if( retcode == SQL_NO_DATA )
  3210. dwVillaCount = 0;
  3211. cmHouseAvail << dwVillaCount;
  3212. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  3213. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  3214. sprintf( szCommand, "SELECT Landblock FROM houses_covenants WHERE HouseType=2 AND OwnerID = %d;",0 );
  3215. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  3216. retcode = SQLExecute( cDatabase::m_hStmt );
  3217. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_CHAR, dwLandblockBuff, sizeof( dwLandblockBuff ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  3218. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i ) {
  3219. sscanf(dwLandblockBuff,"%08x",&dwLandblock);
  3220. cmHouseAvail << dwLandblock;
  3221. }
  3222. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  3223. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  3224. //Determine mansion availability
  3225. sprintf( szCommand, "SELECT COUNT(ID) FROM houses_covenants WHERE HouseType=3 AND OwnerID = %d;",0 );
  3226. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3227. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3228. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwMansionCount, sizeof( dwMansionCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3229. retcode = SQLFetch( cDatabase::m_hStmt );
  3230. if( retcode == SQL_NO_DATA )
  3231. dwMansionCount = 0;
  3232. cmHouseAvail << dwMansionCount;
  3233. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  3234. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  3235. sprintf( szCommand, "SELECT Landblock FROM houses_covenants WHERE HouseType=3 AND OwnerID = %d;",0 );
  3236. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)szCommand, SQL_NTS ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  3237. retcode = SQLExecute( cDatabase::m_hStmt );
  3238. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_CHAR, dwLandblockBuff, sizeof( dwLandblockBuff ), NULL ); CHECKRETURN(1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1)
  3239. for ( i = 0; SQLFetch( cDatabase::m_hStmt ) == SQL_SUCCESS; ++i )
  3240. {
  3241. sscanf(dwLandblockBuff,"%08x",&dwLandblock);
  3242. cmHouseAvail << dwLandblock;
  3243. }
  3244. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN(0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL)
  3245. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND );
  3246. //Determine apartment availability
  3247. sprintf( szCommand, "SELECT COUNT(ID) FROM houses_covenants WHERE HouseType=4 AND OwnerID = %d;",0 );
  3248. retcode = SQLPrepare( cDatabase::m_hStmt, (BYTE *)szCommand, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3249. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3250. retcode = SQLBindCol( cDatabase::m_hStmt, 1, SQL_C_ULONG, &dwApartmentCount, sizeof( dwApartmentCount ), NULL ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  3251. retcode = SQLFetch( cDatabase::m_hStmt );
  3252. if( retcode == SQL_NO_DATA )
  3253. dwApartmentCount = 0;
  3254. retcode = SQLCloseCursor( cDatabase::m_hStmt ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  3255. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_UNBIND ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, NULL )
  3256. cmHouseAvail << dwCottageCount
  3257. << dwVillaCount
  3258. << dwMansionCount
  3259. << dwApartmentCount
  3260. << DWORD(0L);
  3261. AddPacket( WORLD_SERVER, cmHouseAvail, 4 );
  3262. break;
  3263. }
  3264. case ANSWER_POPUP: //0x0275 // Answers a yes/no pop-up question
  3265. {
  3266. DWORD type;
  3267. DWORD confirmSeq;
  3268. DWORD answer;
  3269. CopyMemory( &type, &pbData[12], 4);
  3270. CopyMemory( &confirmSeq, &pbData[16], 4);
  3271. CopyMemory( &answer, &pbData[20], 4);
  3272. cWorldManager::FindPendingConfirm(confirmSeq, answer);
  3273. break;
  3274. }
  3275. case ALLEG_BOOT: //0x0277 // Boot Member by Name
  3276. {
  3277. break;
  3278. }
  3279. case ALLEG_RECALL: //0x0278 // Includes Mansion Recall
  3280. {
  3281. break;
  3282. }
  3283. case SUICIDE: //0x0279 // (@die)
  3284. {
  3285. break;
  3286. }
  3287. case ALLEG_INFO: //0x027B // Retrieve Info by Name
  3288. {
  3289. break;
  3290. }
  3291. case MARKETPLACE_RECALL: //0x028D
  3292. {
  3293. cMessage cmMPAnim = m_pcAvatar->MPAnimate(); //The Marketplace Recall animation
  3294. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmMPAnim, 3 );
  3295. cMessage cmMPMessage = m_pcAvatar->MPMessage(); //The Marketplace Recall animation
  3296. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location,cmMPMessage, 4 );
  3297. m_pcAvatar->m_dwPingCount = 0;
  3298. m_pcAvatar->m_wMarketplace = 1;
  3299. break;
  3300. }
  3301. case PKLITE: //0x028F // (@pklite)
  3302. {
  3303. cMessage cmLSAnim = m_pcAvatar->LSAnimate();
  3304. cWorldManager::SendToAllInFocus( m_pcAvatar->m_Location, cmLSAnim, 3 );
  3305. m_pcAvatar->m_dwPingCount = 0;
  3306. m_pcAvatar->m_wPKlite = 1;
  3307. break;
  3308. }
  3309. case PROMOTE_FELLOW_LEADER: //0x0290
  3310. {
  3311. DWORD dwNewLeaderGUID;
  3312. CopyMemory( &dwNewLeaderGUID, &pbData[12], 4 );
  3313. m_pcAvatar->FellowshipLeader( dwNewLeaderGUID );
  3314. break;
  3315. }
  3316. case OPEN_CLOSE_FELLOWSHIP: //0x0291
  3317. {
  3318. DWORD dwOpen;
  3319. CopyMemory( &dwOpen, &pbData[12], 4 );
  3320. m_pcAvatar->OpenCloseFellowship( dwOpen );
  3321. break;
  3322. }
  3323. //High-Priority Movement Packet
  3324. case MOVEMENT_HIGH_PRIORITY: //0xF753:
  3325. {
  3326. m_pcAvatar->m_wLifeStone = 0;
  3327. cLocation *pcLoc = (cLocation *)&pbData[12];
  3328. /*
  3329. #ifdef _DEBUG
  3330. char szPacketA[120];
  3331. sprintf( szPacketA, "Movement High: H1: %f U1: %f U2: %f H2: %f",pcLoc->m_flA,pcLoc->m_flB, pcLoc->m_flC,pcLoc->m_flW);
  3332. cMasterServer::ServerMessage( ColorYellow2,this,(char *)szPacketA);
  3333. #endif
  3334. */
  3335. cWorldManager::MoveAvatar( this, *pcLoc );
  3336. break; // case 0xF753
  3337. }
  3338. //Low-Priority Movement Packet
  3339. case MOVEMENT_LOW_PRIORITY: //0xF61C:
  3340. {
  3341. m_pcAvatar->m_wLifeStone = 0;
  3342. DWORD *pdwData = (DWORD *)pbData;
  3343. if ( pdwData[3] == 0 || pdwData[3] == 1 )
  3344. {
  3345. cWorldManager::MoveAvatar( this, m_pcAvatar->m_Location, 1 );
  3346. break; // case 0xF61C
  3347. }
  3348. cLocation *pcLoc;
  3349. DWORD dwSkip = 0;
  3350. DWORD dwHex3;
  3351. for ( dwHex3 = pdwData[3]; dwHex3 > 0; dwHex3 >>= 1 )
  3352. if ( dwHex3 & 1 )
  3353. ++dwSkip;
  3354. //Flags
  3355. DWORD dwSpeedFlag = 0, dwTurnFlag = 0, dwSlideFlag = 0;
  3356. DWORD dwMoveFlag = 0, dwEmoteFlag = 0;
  3357. DWORD *pdwDataAt = &pdwData[4];
  3358. WORD wAnim = 0;
  3359. //Cubem0j0: Note: this used to be 1.0
  3360. float flPlaySpeed = 1.0f;
  3361. if ( pdwData[3] & 0x00000001 )
  3362. { //Normal Speed, Unset = Walking
  3363. dwSpeedFlag = *pdwDataAt;
  3364. pdwDataAt += 1;
  3365. }
  3366. if ( pdwData[3] & 0x00000004 )
  3367. { //Moving
  3368. DWORD dwMoveFlag = *pdwDataAt;
  3369. pdwDataAt += 1;
  3370. if ( dwMoveFlag == 0x45000005 )
  3371. {
  3372. //Cubem0j0: Test to see if we can run faster!
  3373. flPlaySpeed = 1.0f;
  3374. if ( dwSpeedFlag == 0 )
  3375. wAnim = 0x05;
  3376. else if ( dwSpeedFlag == 2 )
  3377. wAnim = 0x07;
  3378. }
  3379. else if ( dwMoveFlag == 0x45000006 )
  3380. {
  3381. flPlaySpeed = -1.0f;
  3382. wAnim = 0x05;
  3383. }
  3384. else if ( (dwMoveFlag & 0xFF000000) == 0x41000000 )
  3385. wAnim = (WORD)(dwMoveFlag & 0xFF);
  3386. else if ( (dwMoveFlag & 0xFF000000) == 0x43000000 )
  3387. wAnim = (WORD)(dwMoveFlag & 0xFF);
  3388. }
  3389. if ( pdwData[3] & 0x00000020 )
  3390. { //Sliding
  3391. DWORD dwSlideFlag = *pdwDataAt;
  3392. pdwDataAt += 1;
  3393. if ( dwSlideFlag == 0x6500000F )
  3394. {
  3395. flPlaySpeed = 1.0f;
  3396. wAnim = 0x0F;
  3397. }
  3398. else if ( dwSlideFlag == 0x65000010 )
  3399. {
  3400. flPlaySpeed = -1.0f;
  3401. wAnim = 0x0F;
  3402. }
  3403. }
  3404. if ( pdwData[3] & 0x00000100 )
  3405. { //Turning
  3406. DWORD dwTurnFlag = *pdwDataAt;
  3407. pdwDataAt += 1;
  3408. if ( dwTurnFlag == 0x6500000D ) //Right
  3409. {
  3410. flPlaySpeed = 1.0f;
  3411. wAnim = 0x0D;
  3412. }
  3413. else if ( dwTurnFlag == 0x6500000E ) //Left
  3414. {
  3415. flPlaySpeed = -1.0f;
  3416. wAnim = 0x0D;
  3417. }
  3418. }
  3419. if ( pdwData[3] & 0x0000F800 )
  3420. { //Emote Backlog
  3421. DWORD dwEmoteFlag = *pdwDataAt;
  3422. DWORD dwNumEmotes = (pdwData[3] & 0x0000F800) >> 11;
  3423. pdwDataAt += (dwNumEmotes * 2);
  3424. dwSkip += (dwNumEmotes * 2) - 1;
  3425. if ( dwNumEmotes > 2 ) //For some reason, on 3+ emotes, it has another DWORD at the end
  3426. ++dwSkip;
  3427. //Just play the first one
  3428. wAnim = (WORD)(dwEmoteFlag & 0xFF);
  3429. if ( dwNumEmotes > 1 )
  3430. {
  3431. //Lots of emotes... Learn how to chain later! =]
  3432. }
  3433. cWorldManager::MoveAvatar( this, m_pcAvatar->m_Location, wAnim );
  3434. break; // case 0xF61C
  3435. }
  3436. pcLoc = (cLocation *)&pdwData[4 + dwSkip];
  3437. /*
  3438. #ifdef _DEBUG
  3439. char szPacketA[120];
  3440. sprintf( szPacketA, "Movement Low: H1: %f U1: %f U2: %f H2: %f",pcLoc->m_flA,pcLoc->m_flB, pcLoc->m_flC,pcLoc->m_flW);
  3441. cMasterServer::ServerMessage( ColorYellow2,this,(char *)szPacketA);
  3442. #endif
  3443. */
  3444. cWorldManager::MoveAvatar( this, *pcLoc, wAnim, flPlaySpeed );
  3445. break; // case 0xF61C
  3446. }
  3447. case JUMP:
  3448. {
  3449. char szPacket[60];
  3450. sprintf( szPacket, "F7B1 Packet: %08x",MType2);
  3451. cMasterServer::ServerMessage( ColorYellow,this,(char *)szPacket);
  3452. break;
  3453. }
  3454. default:
  3455. {
  3456. #ifdef _DEBUG
  3457. char szPacket[60];
  3458. sprintf( szPacket, "Unknown F7B1 Packet: %08x",MType2);
  3459. cMasterServer::ServerMessage( ColorYellow,this,(char *)szPacket);
  3460. #endif
  3461. }
  3462. } //end switch ( MType2 )
  3463. break;
  3464. } //end case 0xF7B1
  3465. default:
  3466. {
  3467. #ifdef _DEBUG
  3468. char szPacketA[60];
  3469. sprintf( szPacketA, "Unknown World Packet: %08x",MType1);
  3470. cMasterServer::ServerMessage( ColorYellow2,this,(char *)szPacketA);
  3471. #endif
  3472. }
  3473. } //end switch ( MType1 )
  3474. pbData += FH.m_wFragmentLength - 16;
  3475. } //end while loop
  3476. } //end if conditonal
  3477. break; //case 4
  3478. }
  3479. case 5: //Logout
  3480. {
  3481. cWorldManager::RemoveClient( this );
  3482. m_bWorldState = 1;
  3483. m_bCharState = 8;
  3484. m_dwF7B0Sequence = 0;
  3485. break; //case 5
  3486. }
  3487. } //end switch ( m_bWorldState )
  3488. }