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

CommandParser.cpp 67KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982
  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 CommandParser.cpp
  19. * Implements functionality for command parsing.
  20. *
  21. * Used to parse server-specific commands outside the typical protocol.
  22. */
  23. #include "Client.h"
  24. #include "CommandParser.h"
  25. #include "WorldManager.h"
  26. #include "DataBase.h"
  27. #include "Wand.h"
  28. #include "Job.h"
  29. #include "TreasureGen.h"
  30. DWORD SpawnLimit = 99999999; // 3400 for non developers
  31. cClient *cCommandParser::m_pcClient;
  32. TreasureGen *tgen = new TreasureGen();
  33. /**
  34. * Records an avatar's location to the database.
  35. */
  36. BOOL cCommandParser::RecordLocation( )
  37. {
  38. #ifdef _DEBUG
  39. UpdateConsole( " %s's location being recorded ...\r\n", m_pcClient->m_pcAvatar->m_strName.c_str() );
  40. #endif // _DEBUG
  41. // if ( !strlen( szCommand ) )
  42. // return FormatError( "!recordloc" );
  43. DWORD dwLandBlock = m_pcClient->m_pcAvatar->m_Location.m_dwLandBlock;
  44. // float flX = m_pcClient->m_pcAvatar->m_Location.m_flX;
  45. // float flY = m_pcClient->m_pcAvatar->m_Location.m_flY;
  46. // float flZ = m_pcClient->m_pcAvatar->m_Location.m_flZ;
  47. // float flA = m_pcClient->m_pcAvatar->m_Location.m_flA;
  48. // float flB = m_pcClient->m_pcAvatar->m_Location.m_flB;
  49. // float flC = m_pcClient->m_pcAvatar->m_Location.m_flC;
  50. // float flW = m_pcClient->m_pcAvatar->m_Location.m_flW;
  51. DWORD flX;
  52. DWORD flY;
  53. DWORD flZ;
  54. DWORD flA;
  55. DWORD flB;
  56. DWORD flC;
  57. DWORD flW;
  58. DWORD dwGUID = m_pcClient->m_pcAvatar->m_dwGUID;
  59. BOOL fVerify = TRUE;
  60. char Command[500];
  61. RETCODE retcode;
  62. // floating point to 32-bit hexadecimal
  63. flX = cDatabase::Float2Hex(m_pcClient->m_pcAvatar->m_Location.m_flX);
  64. flY = cDatabase::Float2Hex(m_pcClient->m_pcAvatar->m_Location.m_flY);
  65. flZ = cDatabase::Float2Hex(m_pcClient->m_pcAvatar->m_Location.m_flZ);
  66. flA = cDatabase::Float2Hex(m_pcClient->m_pcAvatar->m_Location.m_flA);
  67. flB = cDatabase::Float2Hex(m_pcClient->m_pcAvatar->m_Location.m_flB);
  68. flC = cDatabase::Float2Hex(m_pcClient->m_pcAvatar->m_Location.m_flC);
  69. flW = cDatabase::Float2Hex(m_pcClient->m_pcAvatar->m_Location.m_flW);
  70. // database code to record start location
  71. sprintf( Command, "UPDATE avatar_location SET Landblock = ('%08x'), Position_X = ('%08x'),Position_Y = ('%08x'),Position_Z = ('%08x'),Orientation_W = ('%08x'),Orientation_X = ('%08x'),Orientation_Y = ('%08x'),Orientation_Z = ('%08x') WHERE AvatarGUID = (%d);",dwLandBlock, flX, flY, flZ, flA, flB, flC, flW, dwGUID );
  72. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)Command, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  73. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  74. if( retcode == SQL_NO_DATA ){
  75. sprintf( Command, "INSERT INTO avatar_location (AvatarGUID, Landblock , Position_X, Position_Y, Position_Z, Orientation_W, Orientation_X, Orientation_Y,Orientation_Z) VALUES (%d,'%08x',%f,%f,%f,%f,%f,%f,%f);",dwGUID,dwLandBlock, flX, flY, flZ, flA, flB, flC, flW );
  76. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)Command, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  77. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  78. }
  79. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_CLOSE ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  80. char szMessage[100];
  81. sprintf( szMessage, " <SQL> Recorded location for %s updated.\r\n",m_pcClient->m_pcAvatar->m_strName.c_str() );
  82. UpdateConsole((char *)szMessage);
  83. return TRUE;
  84. }
  85. /**
  86. * Records an avatar's lifestone to the database.
  87. */
  88. BOOL cCommandParser::RecordLifestone( cLocation pcLoc,DWORD dwGUID )
  89. {
  90. char szMessage[100];
  91. #ifdef _DEBUG
  92. // sprintf( szMessage, " %s's lifestone location being updated ...\r\n", strName );
  93. sprintf( szMessage, " Lifestone location being updated for GUID %d ...\r\n", dwGUID );
  94. UpdateConsole((char *)szMessage);
  95. #endif // _DEBUG
  96. DWORD dwLandBlock = pcLoc.m_dwLandBlock;
  97. // float flX = pcLoc.m_flX;
  98. // float flY = pcLoc.m_flY;
  99. // float flZ = pcLoc.m_flZ;
  100. // float flA = pcLoc.m_flA;
  101. // float flB = pcLoc.m_flB;
  102. // float flC = pcLoc.m_flC;
  103. // float flW = pcLoc.m_flW;
  104. DWORD flX;
  105. DWORD flY;
  106. DWORD flZ;
  107. DWORD flA;
  108. DWORD flB;
  109. DWORD flC;
  110. DWORD flW;
  111. // database code to record lifestone tie
  112. BOOL fVerify = TRUE;
  113. char Command[500];
  114. RETCODE retcode;
  115. // floating point to 32-bit hexadecimal
  116. flX = cDatabase::Float2Hex(pcLoc.m_flX);
  117. flY = cDatabase::Float2Hex(pcLoc.m_flY);
  118. flZ = cDatabase::Float2Hex(pcLoc.m_flZ);
  119. flA = cDatabase::Float2Hex(pcLoc.m_flA);
  120. flB = cDatabase::Float2Hex(pcLoc.m_flB);
  121. flC = cDatabase::Float2Hex(pcLoc.m_flC);
  122. flW = cDatabase::Float2Hex(pcLoc.m_flW);
  123. sprintf( Command, "UPDATE avatar_location SET LS_LandBlock = ('%08x'), LS_Position_X = ('%08x'),LS_Position_Y = ('%08x'), LS_Position_Z = ('%08x'), LS_Orientation_W = ('%08x'), LS_Orientation_X = ('%08x'), LS_Orientation_Y = ('%08x'), LS_Orientation_Z = ('%08x') WHERE AvatarGUID = (%d);",dwLandBlock, flX, flY, flZ, flA, flB, flC, flW, dwGUID );
  124. // sprintf( Command, "UPDATE avatar_location SET LS_LandBlock = ('%08x'), LS_Position_X = (%f), LS_Position_Y = (%f), LS_Position_Z = (%f), LS_Orientation_W = (%f), LS_Orientation_X = (%f), LS_Orientation_Y = (%f), LS_Orientation_Z = (%f) WHERE AvatarGUID = (%d);",dwLandBlock, flX, flY, flZ, flA, flB, flC, flW, dwGUID );
  125. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)Command, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  126. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  127. if( retcode == SQL_NO_DATA ){
  128. sprintf( Command, "INSERT INTO avatar_location (AvatarGUID, LS_LandBlock , LS_Position_X, LS_Position_Y, LS_Position_Z, LS_Orientation_W, LS_Orientation_X, LS_Orientation_Y, LS_Orientation_Z) VALUES (%d,'%08x',%f,%f,%f,%f,%f,%f,%f);",dwGUID,dwLandBlock, flX, flY, flZ, flA, flB, flC, flW );
  129. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)Command, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  130. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  131. }
  132. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_CLOSE ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  133. // sprintf( szMessage, " <SQL> Lifestone location for %s updated.\r\n", m_pcClient->m_pcAvatar->m_strName.c_str() );
  134. sprintf( szMessage, " <SQL> Lifestone location for GUID %d updated.\r\n", dwGUID );
  135. UpdateConsole((char *)szMessage);
  136. return TRUE;
  137. }
  138. BOOL cCommandParser::Turn( char *szHeading)
  139. {
  140. char *szStopString;
  141. DWORD dwAnim = strtoul( szHeading, &szStopString, 10 );
  142. char szMessage[100];
  143. sprintf( szMessage, "Turn: %u\r\n",dwAnim);
  144. //UpdateConsole((char *)szMessage);
  145. int job = cMasterServer::m_pcJobPool->CreateJob( &cAvatar::CastMain, NULL, NULL, "test", dwAnim, 1);
  146. //sprintf( szMessage, "JobID: %u\r\n",job);
  147. UpdateConsole((char *)szMessage);
  148. //cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, m_pcClient->m_pcAvatar->TurnToTarget(dwAnim, 80670535), 3);
  149. return TRUE;
  150. }
  151. /**
  152. * Teleports an avatar to the specified world location.
  153. * The location is specified as a set of N/S and E/W coordinates
  154. *
  155. * @param *szLocation - A pointer to the text representing the location to which to teleport the avatar.
  156. */
  157. BOOL cCommandParser::Telemap( char *szLocation )
  158. {
  159. #ifdef _DEBUG
  160. UpdateConsole( " TeleMap command issued by %s.\r\n", m_pcClient->m_pcAvatar->m_strName.c_str() );
  161. #endif // _DEBUG
  162. if( !lstrlen( szLocation ) )
  163. return FormatError( "!telemap" );
  164. double dNS, dEW;
  165. char *szTextEnd = szLocation + strlen( szLocation );
  166. char *szCur = szLocation;
  167. if ( szCur >= szTextEnd )
  168. return FormatError( "!telemap" );
  169. dNS = strtod( szCur, &szCur );
  170. if ( szCur >= szTextEnd )
  171. return FormatError( "!telemap" );
  172. if ( ( dNS == 0 ) && ( *szLocation != '0' ) || dNS > 100.0 || dNS < 0.0 )
  173. return FormatError( "!telemap" );
  174. if ( ( *szCur == 'S' ) || ( *szCur == 's' ) )
  175. dNS *= -1;
  176. dEW = strtod( szCur + 2, &szCur );
  177. if ( ( dEW == 0 ) && ( szCur != ( szTextEnd-1 ) ) || dEW > 100.0 || dEW < 0.0 )
  178. return FormatError( "!telemap" );
  179. if ( ( *szCur == 'W' ) || ( *szCur == 'w' ) )
  180. dEW *= -1;
  181. cLocation Loc;
  182. Loc.m_flX = ( dEW * 10.0f + 1020.0f ) * 24.0f;
  183. Loc.m_flY = ( dNS * 10.0f - 1020.0f ) * 24.0f;
  184. Loc.m_flZ = 0.0f;//500.0f; Set to zero always will portal to height of the landmass
  185. Loc.m_dwLandBlock =
  186. ( ( BYTE ) ( ( ( ( DWORD )Loc.m_flX % 192 ) / 24 ) * 8 ) + ( ( ( DWORD )Loc.m_flY % 192 ) / 24) ) |
  187. ( ( 0x00 ) << 8) |
  188. ( ( BYTE ) ( Loc.m_flY / 192.0f ) << 16) |
  189. ( ( BYTE ) ( Loc.m_flX / 192.0f ) << 24 ) ;
  190. Loc.m_dwLandBlock -= 0x00010000;
  191. Loc.m_flX = ( float )( ( int ) Loc.m_flX % 192);
  192. Loc.m_flY = ( float )( ( int ) Loc.m_flY % 192);
  193. cWorldManager::TeleportAvatar( m_pcClient, Loc );
  194. return TRUE;
  195. }
  196. /**
  197. * Teleports an avatar to the specified world location.
  198. * The location is specified as a hexadecimal landblock and decimal X, Y, and Z coordinates.
  199. *
  200. * @param *szLocation - A pointer to the text representing the location to which to teleport the avatar.
  201. */
  202. BOOL cCommandParser::TeleLoc( char *szLocation )
  203. {
  204. #ifdef _DEBUG
  205. UpdateConsole( " TeleLoc command issued by %s.\r\n", m_pcClient->m_pcAvatar->m_strName.c_str() );
  206. #endif // _DEBUG
  207. if( !lstrlen( szLocation ) )
  208. return FormatError( "!teleloc" );
  209. //DWORD dwlandblock;
  210. float flX,flY,flZ,flH;
  211. char *szTextEnd = szLocation + strlen( szLocation );
  212. char *szCur = szLocation;
  213. cLocation Loc;
  214. if ( szCur >= szTextEnd )
  215. return FormatError( "!teleloc" );
  216. sscanf(szCur,"%08x",&Loc.m_dwLandBlock);
  217. if ( szCur >= szTextEnd )
  218. return FormatError( "!teleloc" );
  219. //if (&Loc.m_dwLandBlock <
  220. szCur = szCur + 8;
  221. flX = strtod( ++szCur, &szCur );
  222. if ( szCur >= szTextEnd )
  223. return FormatError( "!teleloc" );
  224. flY = strtod( ++szCur, &szCur );
  225. if ( szCur >= szTextEnd )
  226. return FormatError( "!teleloc" );
  227. flZ = strtod( ++szCur, &szCur );
  228. if ( szCur >= szTextEnd )
  229. return FormatError( "!teleloc" );
  230. flH = strtod( szCur, &szCur );
  231. if ( szCur > szTextEnd)
  232. return FormatError( "!teleloc" );
  233. Loc.m_flX = flX;
  234. Loc.m_flY = flY;
  235. Loc.m_flZ = flZ;
  236. Loc.m_flW = flH;
  237. cWorldManager::TeleportAvatar( m_pcClient, Loc );
  238. return TRUE;
  239. }
  240. /**
  241. * Teleports an avatar to the specified town or region location.
  242. *
  243. * @param *szTown - A pointer to the text representing the name of the location to which to teleport the avatar.
  244. *
  245. * Authors: Cubem0j0 & eLeM
  246. */
  247. BOOL cCommandParser::TeleTown( char *szTown )
  248. {
  249. #ifdef _DEBUG
  250. UpdateConsole( " TeleTown command issued by %s.\r\n", m_pcClient->m_pcAvatar->m_strName.c_str() );
  251. #endif // _DEBUG
  252. char *szTextEnd = szTown + strlen( szTown );
  253. char *szCur = szTown;
  254. char *szName;
  255. if ( szCur >= szTextEnd )
  256. return FormatError( "!teletown" );
  257. szName = szCur + 1;
  258. if ( szName >= szTextEnd )
  259. return FormatError( "!teletown" );
  260. szCur = strchr( szName, '"' );
  261. if ( szCur >= szTextEnd || szCur == NULL )
  262. return FormatError( "!teletown" );
  263. *szCur = '\0';
  264. for( std::vector<cTeleTownList>::iterator iterTeleTown_lst = cMasterServer::m_TeleTownList.begin(); iterTeleTown_lst != cMasterServer::m_TeleTownList.end(); iterTeleTown_lst++ )
  265. {
  266. if ( strcmp (iterTeleTown_lst->m_teleString.c_str( ),szName) == 0 )
  267. {
  268. static cLocation townLoc;
  269. townLoc.m_dwLandBlock = iterTeleTown_lst->m_dwLandblock;
  270. townLoc.m_flX = iterTeleTown_lst->m_flPosX;
  271. townLoc.m_flY = iterTeleTown_lst->m_flPosY;
  272. townLoc.m_flZ = iterTeleTown_lst->m_flPosZ;
  273. townLoc.m_flA = iterTeleTown_lst->m_flOrientW;
  274. townLoc.m_flB = iterTeleTown_lst->m_flOrientX;
  275. townLoc.m_flC = iterTeleTown_lst->m_flOrientY;
  276. townLoc.m_flW = iterTeleTown_lst->m_flOrientZ;
  277. cWorldManager::TeleportAvatar(m_pcClient, townLoc);
  278. return true;
  279. }
  280. }
  281. return FormatError( "!teletown" );
  282. }
  283. //// Town/Area Locations (Portal Drops) ////
  284. /*
  285. Marketplace 0x016C01BC [49.206001 -31.934999 0.005000] 0.707107 0.000000 0.000000 -0.707107
  286. Aerlinthe Island 0xBAE8001D [84.00000 105.000000 26.004999] 0.000000 0.000000 0.000000 -1.000000
  287. Ahurenga 0x0FB90009 [43.000000 8.600000 0.005000] -0.980098 0.000000 0.000000 -0.198513
  288. Al-Arqas 0x8F58003B [183.850998 60.182999 9.325916] 0.707107 0.000000 0.000000 -0.707107
  289. Al-Jalima 0x8588002C [120.359001 95.470001 90.049164] 1.000000 0.000000 0.000000 0.000000
  290. Arwic 0xC6A90009 [46.805000 4.219000 42.005001] 1.000000 0.000000 0.000000 0.000000
  291. Ayan Baqur (approximate) 0x11340025 [99.810356 107.909721 42.005001] 0.710993 0.000000 0.000000 -0.703199
  292. Baishi 0xCE410007 [12.600000 152.800003 55.055000] -0.544639 0.000000 0.000000 -0.838671
  293. Bandit Castle 0xBDD00006 [16.900000 120.500000 115.099998] 0.707107 0.000000 0.000000 -0.707107
  294. Beach Fort 0x42DE000C [25.000000 84.500000 0.005000] -0.681998 0.000000 0.000000 -0.731354
  295. Bluespire 0x21B00017 [48.189999 165.889999 0.005000] -0.083617 0.000000 0.000000 -0.996498
  296. Candeth Keep (approximate) 0x2B11003D [189.138062 98.801079 48.005001] -0.929239 0.000000 0.000000 -0.369478
  297. Cragstone 0xBB9F0040 [169.358002 168.251007 54.005001] 0.578683 0.000000 0.000000 -0.815552
  298. Crater Lake Village 0x90D00107 [95.521004 84.000000 277.204987] -0.707107 0.000000 0.000000 -0.707107
  299. Danby's Outpost 0x5A9C0004 [23.500000 77.099998 6.005000] 0.000000 0.000000 0.000000 -1.000000
  300. Dryreach 0xDB75003B [186.000000 65.000000 36.088333] -0.751840 0.000000 0.000000 -0.659346
  301. Eastham 0xCE940035 [151.052994 112.610001 17.417250] -0.936577 0.000000 0.000000 -0.350461
  302. Fort Tethana 0x2681001D [77.699997 108.099998 240.004990] -0.522498 0.000000 0.000000 -0.852640
  303. Glenden Wood 0xA0A40025 [96.302002 119.847000 59.954666] 0.707107 0.000000 0.000000 -0.707107
  304. Greenspire 0x2BB5003C [178.957993 86.570000 0.005000] 0.352348 0.000000 0.000000 -0.935869
  305. Hebian-To 0xE64E002F [138.304001 161.904999 20.039833] 0.923880 0.000000 0.000000 -0.382683
  306. Holtburg 0xA9B40019 [84.000000 7.100000 94.005005] 0.996917 0.000000 0.000000 -0.078459
  307. Kara 0xBA170039 [181.199997 3.200000 167.604996] -0.848048 0.000000 0.000000 -0.529919
  308. Khayyaban 0x9F44001A [90.000000 24.552999 36.551083] -0.782608 0.000000 0.000000 -0.622515
  309. Kryst 0xE822002A [132.699997 37.900002 20.105001] -0.866025 0.000000 0.000000 -0.500000
  310. Lin 0xDC3C0011 [59.720001 10.774000 18.051666] -0.358368 0.000000 0.000000 -0.933580
  311. Linvak Tukal 0xA21E001A [83.000000 38.000000 560.362488] 1.000000 0.000000 0.000000 0.000000
  312. Lytelthorpe 0xC0800007 [11.723000 155.559998 33.028084] -0.402363 0.000000 0.000000 -0.915480
  313. MacNiall's Freehold 0xF224001A [81.800003 33.000000 0.005000] 0.241075 0.000000 0.000000 -0.970507
  314. Mayoi 0xE6320021 [107.417000 10.763000 29.907833] -0.642788 0.000000 0.000000 -0.766044
  315. Nanto 0xE63E0022 [96.959999 37.722000 74.574501] 0.000000 0.000000 0.000000 -1.000000
  316. Neydisa Castle 0x95D60033 [146.899994 71.300003 99.763336] -0.731354 0.000000 0.000000 -0.681998
  317. Oolatanga's Refuge 0xF6820033 [145.699997 49.855000 58.005001] -0.467544 0.000000 0.000000 -0.883970
  318. Plateau Village 0x49B70021 [100.099998 20.799999 238.613327] -0.587785 0.000000 0.000000 -0.809017
  319. Qalaba'r 0x9722003A [168.354004 24.618000 102.005005] -0.922790 0.000000 0.000000 -0.385302
  320. Redspire 0x17B2002A [132.623001 25.809000 44.005001] 0.998483 0.000000 0.000000 -0.055063
  321. Rithwic 0xC98C0028 [113.665604 190.259003 22.004999] -0.707107 0.000000 0.000000 -0.707107
  322. Samsur 0x977B000C [25.811001 73.852997 0.005000] 0.929950 0.000000 0.000000 -0.367686
  323. Sawato 0xC95B0001 [14.800000 0.300000 12.004999] 0.930418 0.000000 0.000000 -0.366501
  324. Shoushi 0xDA55001D [84.800003 99.000000 20.004999] 1.000000 0.000000 0.000000 0.000000
  325. Singularity Caul Island 0x09040008 [11.400000 188.600006 87.521667] -0.996345 0.000000 0.000000 -0.085417
  326. Stonehold 0x64D5000B [30.000000 50.000000 78.005005] 0.843391 0.000000 0.000000 -0.537300
  327. Timaru 0x1DB60025 [98.500000 98.099998 120.005005] 0.810042 0.000000 0.000000 -0.586372
  328. Tou-Tou 0xF65C002B [126.387001 54.146999 20.004999] 0.928645 0.000000 0.000000 -0.370971
  329. Tufa 0x876C0008 [2.000000 186.899994 18.004999] -0.707107 0.000000 0.000000 -0.707107
  330. Underground City 0x01E901AD [120.000000 -130.000000 -11.995001] -0.714424 0.000000 0.000000 -0.699713
  331. Uziz 0xA260003C [182.919006 87.933998 20.004999] -0.363463 0.000000 0.000000 -0.931609
  332. Wai Jhou (approximate) 0x3F31001F [83.100197 156.191559 2.780049] 0.539960 0.000000 0.000000 0.841691
  333. Xarabydun 0x934B0021 [108.300430 6.099015 18.144159] -0.964557 0.000000 0.000000 -0.263873
  334. Yanshi 0xB46F001E [75.199997 124.099998 34.688335] 1.000000 0.000000 0.000000 0.000000
  335. Yaraq 0x7D64000D [31.900000 104.599998 11.946667] 0.577145 0.000000 0.000000 -0.816642
  336. Zaikhal 0x80900013 [64.862999 55.687000 124.005005] -0.929882 0.000000 0.000000 -0.367857
  337. // Throne of Destiny //
  338. Eastwatch 0x49F00013 [70.000000 70.000000 170.004990] 0.675590 0.000000 0.000000 -0.737277
  339. Fiun Outpost
  340. Kor-Gursha
  341. Mar'uun
  342. Merwart Village
  343. Sanamar 0x33D90015 [59.099998 100.300003 52.005001] 0.000000 0.000000 0.000000 -1.000000
  344. Silyun 0x26EC003D [175.927002 110.334000 80.005005] 0.673993 0.000000 0.000000 -0.738738
  345. Westwatch
  346. */
  347. /**
  348. * Spawns the item in the avatar's inventory.
  349. *
  350. * @param *szItem - A pointer to the text representing the item's model ID.
  351. *
  352. * Author: Cubem0j0
  353. */
  354. BOOL cCommandParser::SpawnItem ( char *szItem )
  355. {
  356. if ( !lstrlen( szItem ) )
  357. return FormatError( "!SpawnItem" );
  358. char *szStopString;
  359. DWORD dwItemModelID = strtoul( szItem, &szStopString, 10 );
  360. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Spawning item %lu.", dwItemModelID );
  361. //Cubem0j0: We find the model number so we can get some vars.
  362. cItemModels *pcModel = cItemModels::FindModel(dwItemModelID);
  363. if (!pcModel)
  364. return FALSE;
  365. switch(pcModel->m_ItemType)
  366. {
  367. case 0:
  368. {
  369. tgen->CreateMisc(m_pcClient,dwItemModelID);
  370. break;
  371. }
  372. case 1:
  373. {
  374. tgen->CreateWeapon(m_pcClient,dwItemModelID,NULL,0);
  375. break;
  376. }
  377. case 2:
  378. {
  379. tgen->CreateFood(m_pcClient,dwItemModelID,0);
  380. break;
  381. }
  382. case 3:
  383. {
  384. tgen->CreateArmor(m_pcClient,dwItemModelID);
  385. break;
  386. }
  387. case 4:
  388. {
  389. tgen->CreateBook(m_pcClient,dwItemModelID,NULL);
  390. break;
  391. }
  392. case 5:
  393. {
  394. tgen->CreateScrolls(m_pcClient,dwItemModelID);
  395. break;
  396. }
  397. case 6:
  398. {
  399. tgen->CreateHealingKit(m_pcClient,dwItemModelID);
  400. break;
  401. }
  402. case 7:
  403. {
  404. tgen->CreateLockpicks(m_pcClient,dwItemModelID);
  405. break;
  406. }
  407. case 8:
  408. {
  409. tgen->CreateWand(m_pcClient,dwItemModelID,NULL);
  410. break;
  411. }
  412. case 9:
  413. {
  414. tgen->CreatePyreals(m_pcClient,dwItemModelID, DWORD(0x03),WORD(0x0003));
  415. break;
  416. }
  417. case 10:
  418. {
  419. tgen->CreateManastone(m_pcClient,dwItemModelID);
  420. break;
  421. }
  422. case 11:
  423. {
  424. tgen->CreateAmmo(m_pcClient,dwItemModelID);
  425. break;
  426. }
  427. case 12:
  428. {
  429. tgen->CreateShield(m_pcClient,dwItemModelID);
  430. break;
  431. }
  432. case 13:
  433. {
  434. tgen->CreateSpellComponents(m_pcClient,dwItemModelID,NULL);
  435. break;
  436. }
  437. case 14:
  438. {
  439. tgen->CreateGem(m_pcClient,dwItemModelID,NULL);
  440. break;
  441. }
  442. case 15:
  443. {
  444. tgen->CreateTradeNotes(m_pcClient,dwItemModelID);
  445. break;
  446. }
  447. case 16:
  448. {
  449. tgen->CreateTradeSkillMats(m_pcClient,dwItemModelID);
  450. break;
  451. }
  452. case 17:
  453. {
  454. tgen->CreatePlants(m_pcClient,dwItemModelID);
  455. break;
  456. }
  457. case 18:
  458. {
  459. tgen->CreateClothes(m_pcClient,dwItemModelID);
  460. break;
  461. }
  462. case 19:
  463. {
  464. tgen->CreateJewelry(m_pcClient,dwItemModelID);
  465. break;
  466. }
  467. case 20:
  468. {
  469. tgen->CreatePack(m_pcClient,dwItemModelID);
  470. break;
  471. }
  472. case 21:
  473. {
  474. tgen->CreateSalvage(m_pcClient,dwItemModelID);
  475. break;
  476. }
  477. case 22:
  478. {
  479. tgen->CreateFoci(m_pcClient,dwItemModelID);
  480. break;
  481. }
  482. }
  483. return TRUE;
  484. }
  485. /**
  486. * Spawns the item in the avatar's landblock.
  487. *
  488. * @param *szItem - A pointer to the text representing the item's model ID.
  489. *
  490. * Author: Cubem0j0
  491. */
  492. BOOL cCommandParser::SpawnItemLB (char *szItem)
  493. {
  494. if ( !lstrlen( szItem ) )
  495. return FormatError( "!SpawnItemLB" );
  496. char *szStopString;
  497. DWORD dwItemModelID = strtoul( szItem, &szStopString, 10 );
  498. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Spawning item %lu.", dwItemModelID );
  499. //Cubem0j0: We find the model number so we can get some vars.
  500. cItemModels *pcModel = cItemModels::FindModel(dwItemModelID);
  501. if (!pcModel)
  502. return FALSE;
  503. switch(pcModel->m_ItemType)
  504. {
  505. case 1:
  506. {
  507. tgen->CreateWeapon(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  508. break;
  509. }
  510. case 2:
  511. {
  512. tgen->CreateFood(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  513. break;
  514. }
  515. case 3:
  516. {
  517. tgen->CreateArmor(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  518. break;
  519. }
  520. case 4:
  521. {
  522. tgen->CreateBook(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  523. break;
  524. }
  525. case 5:
  526. {
  527. tgen->CreateScrolls(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  528. break;
  529. }
  530. case 6:
  531. {
  532. break;
  533. }
  534. case 7:
  535. {
  536. //ToDo: Lockpicks
  537. break;
  538. }
  539. case 8:
  540. {
  541. tgen->CreateWand(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  542. break;
  543. }
  544. case 9:
  545. {
  546. tgen->CreatePyreals(m_pcClient->m_pcAvatar->m_Location,dwItemModelID,DWORD(0x10),WORD(0x0010));
  547. break;
  548. }
  549. case 10:
  550. {
  551. tgen->CreateManastone(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  552. break;
  553. }
  554. case 11:
  555. {
  556. tgen->CreateAmmo(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  557. break;
  558. }
  559. case 12:
  560. {
  561. tgen->CreateShield(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  562. break;
  563. }
  564. case 13:
  565. {
  566. tgen->CreateSpellComponents(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  567. break;
  568. }
  569. case 14:
  570. {
  571. tgen->CreateGem(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  572. break;
  573. }
  574. case 15:
  575. {
  576. tgen->CreateTradeNotes(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  577. break;
  578. }
  579. case 16:
  580. {
  581. tgen->CreateTradeSkillMats(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  582. break;
  583. }
  584. case 17:
  585. {
  586. tgen->CreatePlants(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  587. break;
  588. }
  589. case 18:
  590. {
  591. tgen->CreateClothes(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  592. break;
  593. }
  594. case 19:
  595. {
  596. tgen->CreateJewelry(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  597. break;
  598. }
  599. case 20:
  600. {
  601. tgen->CreatePack(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  602. break;
  603. }
  604. case 21:
  605. {
  606. tgen->CreateSalvage(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  607. break;
  608. }
  609. case 22:
  610. {
  611. tgen->CreateFoci(m_pcClient->m_pcAvatar->m_Location,dwItemModelID);
  612. break;
  613. }
  614. }
  615. return TRUE;
  616. }
  617. BOOL cCommandParser::SpwnID( char *szText )
  618. {
  619. char *szTextEnd = szText + strlen( szText );
  620. char *szCur = szText;
  621. char *szName;
  622. if ( szCur >= szTextEnd )
  623. return FormatError( "!spwnid" );
  624. DWORD dwModel = strtoul( szCur, &szCur, 10 );
  625. if ( szCur >= szTextEnd )
  626. return FormatError( "!spwnid" );
  627. if (dwModel > SpawnLimit)
  628. {
  629. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Spawning item %lu.", dwModel );
  630. return TRUE;
  631. }
  632. szName = szCur + 2;
  633. if ( szName >= szTextEnd )
  634. return FormatError( "!spwnid" );
  635. szCur = strchr( szName, '"' );
  636. if ( szCur >= szTextEnd || szCur == NULL )
  637. return FormatError( "!spwnid" );
  638. *szCur = '\0';
  639. DWORD dwIcon = 1024;
  640. float flScale = 1.0;
  641. BOOL fSolid = 0;
  642. BOOL fSelectable = 1;
  643. BOOL fEquippable = 1;
  644. std::ostringstream ssDescription;
  645. ssDescription << "Model #" << dwModel;
  646. cAbiotic *pcModel = new cAbiotic( cWorldManager::NewGUID_Object( ), m_pcClient->m_pcAvatar->m_Location, dwModel, flScale, fSolid, dwIcon, szName, ssDescription.str( ), 500, 2500, fSelectable, fEquippable );
  647. pcModel->SetStatic( FALSE );
  648. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Spawning item %lu.", dwModel );
  649. cWorldManager::AddObject( pcModel );
  650. return TRUE;
  651. }
  652. /*
  653. Cubem0j0: Icons appear to stop somewhere between 3042 and 3067
  654. 4160 - 4169 food
  655. 4170 - Well
  656. */
  657. BOOL cCommandParser::SpawnID( char *szText )
  658. {
  659. #ifdef _DEBUG
  660. UpdateConsole( "Object being spawned.\r\n" );
  661. #endif // _DEBUG
  662. char *szTextEnd = szText + strlen( szText );
  663. char *szCur = szText;
  664. char *szName;
  665. if ( szCur >= szTextEnd )
  666. return FormatError( "!spawnid" );
  667. DWORD dwModel = strtoul( szCur, &szCur, 10 );
  668. if ( szCur >= szTextEnd )
  669. return FormatError( "!spawnid" );
  670. if (dwModel > SpawnLimit){
  671. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Spawning item %lu.", dwModel );
  672. return TRUE;
  673. }
  674. DWORD dwIcon = strtoul( ++szCur, &szCur, 10 );
  675. if ( szCur >= szTextEnd )
  676. return FormatError( "!spawnid" );
  677. szName = szCur + 2;
  678. if ( szName >= szTextEnd )
  679. return FormatError( "!spawnid" );
  680. szCur = strchr( szName, '"' );
  681. if ( szCur >= szTextEnd || szCur == NULL )
  682. return FormatError( "!spawnid" );
  683. *szCur = '\0';
  684. BOOL fSelectable = strtoul( ++szCur, &szCur, 10 );
  685. if ( szCur >= szTextEnd )
  686. return FormatError( "!spawnid" );
  687. //
  688. BOOL fEquippable = strtoul( ++szCur, &szCur, 10 );
  689. if ( szCur >= szTextEnd )
  690. return FormatError( "!spawnid" );
  691. //
  692. float flScale = strtod( ++szCur, &szCur );
  693. if( flScale <= 0.0 )
  694. flScale = 1.0;
  695. BOOL fSolid = strtoul( ++szCur, &szCur, 10 );
  696. std::ostringstream ssDescription;
  697. ssDescription << "Model #" << dwModel;
  698. cAbiotic *pcModel = new cAbiotic( cWorldManager::NewGUID_Object( ), m_pcClient->m_pcAvatar->m_Location, dwModel, flScale, fSolid, dwIcon, szName, ssDescription.str( ), 500, 2500, fSelectable, fEquippable );
  699. pcModel->SetStatic( FALSE );
  700. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Spawning item %lu.", dwModel );
  701. cWorldManager::AddObject( pcModel );
  702. return TRUE;
  703. }
  704. /**
  705. * Implements global chatting.
  706. *
  707. * @param *szText - A pointer to the text representing the message to display.
  708. */
  709. BOOL cCommandParser::GlobalChat( char *szText )
  710. {
  711. if ( !lstrlen( szText ) )
  712. return FormatError( "!global" );
  713. cMasterServer::ServerMessage( ColorYellow, NULL, "%s shouts, \"%s\"", m_pcClient->m_pcAvatar->Name( ), szText );
  714. return TRUE;
  715. }
  716. /**
  717. * Displays a specified animation.
  718. *
  719. * @param *szAnimation - A pointer to the text representing the animation to display.
  720. */
  721. BOOL cCommandParser::Animation( char *szAnimation )
  722. {
  723. #ifdef _DEBUG
  724. //UpdateConsole( "Viewing animation effect.\r\n" );
  725. #endif // _DEBUG
  726. if ( !lstrlen( szAnimation ) )
  727. return FormatError( "!animation" );
  728. char *szStopString;
  729. DWORD dwAnim = strtoul( szAnimation, &szStopString, 10 );
  730. cMessage cAnim = m_pcClient->m_pcAvatar->Animation( dwAnim, 1.0f );
  731. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Now showing animation #%u.", dwAnim );
  732. cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, cAnim, 3 );
  733. return TRUE;
  734. }
  735. /**
  736. * Displays a specified particle effect.
  737. *
  738. * @param *szParticle - A pointer to the text representing the particle effect to display.
  739. */
  740. BOOL cCommandParser::Particle( char *szParticle )
  741. {
  742. #ifdef _DEBUG
  743. UpdateConsole( " Viewing particle effect.\r\n" );
  744. #endif // _DEBUG
  745. if ( !lstrlen( szParticle ) )
  746. return FormatError( "!particle" );
  747. char *szStopString;
  748. DWORD dwParticle = strtoul( szParticle, &szStopString, 10 );
  749. cMessage cPart = m_pcClient->m_pcAvatar->Particle( dwParticle );
  750. cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, cPart, 3 );
  751. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Now showing particle #%u.", dwParticle );
  752. return TRUE;
  753. }
  754. /**
  755. * Plays a specified sound effect.
  756. *
  757. * @param *szSound - A pointer to the text representing the sound effect to display.
  758. */
  759. BOOL cCommandParser::SoundEffect( char *szSound )
  760. {
  761. #ifdef _DEBUG
  762. UpdateConsole( " Listening to sound effect.\r\n" );
  763. #endif // _DEBUG
  764. if ( !lstrlen( szSound ) )
  765. return FormatError( "!sound" );
  766. char *szStopString;
  767. DWORD dwSound = strtoul( szSound, &szStopString, 10 );
  768. cMessage cPart = m_pcClient->m_pcAvatar->SoundEffect( dwSound, 1 );
  769. cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, cPart, 3 );
  770. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Now playing sound #%u.", dwSound );
  771. return TRUE;
  772. }
  773. /**
  774. * Clears all objects from the server.
  775. */
  776. BOOL cCommandParser::ClearObjects( )
  777. {
  778. cWorldManager::RemoveAllObjects();
  779. cMasterServer::ServerMessage( ColorGreen, NULL, "The server administrator has cleared all of the objects." );
  780. return TRUE;
  781. }
  782. /**
  783. * Displays a world broadcast to the server.
  784. *
  785. * @param *szText - A pointer to the text representing the message to display.
  786. */
  787. BOOL cCommandParser::WorldBroadcast( char *szText )
  788. {
  789. #ifdef _DEBUG
  790. UpdateConsole( " World broadcast occuring.\r\n" );
  791. #endif // _DEBUG
  792. if ( !lstrlen( szText ) )
  793. return FormatError( "!wb" );
  794. cMasterServer::ServerMessage( ColorGreen, NULL, szText );
  795. return TRUE;
  796. }
  797. /**
  798. * Summons a player to the avatar's location.
  799. * Intended to be used in conjunction with cCommandParser::ReturnCharacter.
  800. *
  801. * @param *szText - A pointer to the text representing the name of the character to summon.
  802. */
  803. BOOL cCommandParser::GetCharacter( char *szText )
  804. {
  805. #ifdef _DEBUG
  806. UpdateConsole( " Teleporting character to you ...\r\n" );
  807. #endif // _DEBUG
  808. if ( !lstrlen( szText ) )
  809. return FormatError( "!getchar" );
  810. cClient* pcClient = cClient::FindClient( szText );
  811. if( pcClient == NULL )
  812. {
  813. cMasterServer::ServerMessage( ColorRed, m_pcClient, "!getchar failed. Invalid character." );
  814. return FALSE;
  815. }
  816. std::stringstream strstrmR;
  817. strstrmR << "You have been summoned by " << m_pcClient->m_pcAvatar->m_strName << "...";
  818. cMasterServer::ServerMessage( ColorGreen, pcClient, ( char * )strstrmR.str( ).c_str( ) );
  819. std::stringstream strstrmL;
  820. strstrmL << "Summoning " << pcClient->m_pcAvatar->m_strName << " to you...";
  821. cMasterServer::ServerMessage( ColorGreen, m_pcClient, ( char * )strstrmL.str( ).c_str( ) );
  822. CopyMemory( &pcClient->m_pcAvatar->m_PreviousLocation, &pcClient->m_pcAvatar->m_Location, sizeof( cLocation ) );
  823. cWorldManager::TeleportAvatar( pcClient, m_pcClient->m_pcAvatar->m_Location );
  824. return TRUE;
  825. }
  826. /**
  827. * Teleports an avatar to the player's location.
  828. *
  829. * @param *szText - A pointer to the text representing the name of the character to whom to teleport.
  830. */
  831. BOOL cCommandParser::GotoCharacter( char *szText )
  832. {
  833. #ifdef _DEBUG
  834. UpdateConsole( " Teleporting to character location ...\r\n" );
  835. #endif // _DEBUG
  836. if ( !lstrlen( szText ) )
  837. return FormatError( "!gotochar" );
  838. cClient* pcClient = cClient::FindClient( szText );
  839. if( pcClient == NULL )
  840. {
  841. cMasterServer::ServerMessage( ColorRed, m_pcClient, "!gotochar failed. Invalid character." );
  842. return FALSE;
  843. }
  844. std::stringstream strstrmL;
  845. strstrmL << "Going to character " << pcClient->m_pcAvatar->m_strName << "...";
  846. cMasterServer::ServerMessage( ColorGreen, m_pcClient, ( char * )strstrmL.str( ).c_str( ) );
  847. cWorldManager::TeleportAvatar( m_pcClient, pcClient->m_pcAvatar->m_Location );
  848. return TRUE;
  849. }
  850. /**
  851. * Returns a player to his or her previous location.
  852. * Intended to be used in conjunction with cCommandParser::GetCharacter.
  853. *
  854. * @param *szText - A pointer to the text representing the name of the character to whom to teleport.
  855. */
  856. BOOL cCommandParser::ReturnCharacter( char *szText )
  857. {
  858. #ifdef _DEBUG
  859. UpdateConsole( " Returning character to previous location ...\r\n" );
  860. #endif // _DEBUG
  861. if ( !lstrlen( szText ) )
  862. return FormatError( "!returnchar" );
  863. cClient* pcClient = cClient::FindClient( szText );
  864. if( pcClient == NULL )
  865. {
  866. cMasterServer::ServerMessage( ColorRed, m_pcClient, "!returnchar failed, invalid char" );
  867. return FALSE;
  868. }
  869. else if( pcClient->m_pcAvatar->m_PreviousLocation.m_dwLandBlock == NULL)
  870. {
  871. cMasterServer::ServerMessage( ColorRed, m_pcClient, "!returnchar failed. No previous location is available." );
  872. return FALSE;
  873. }
  874. std::stringstream strstrmR;
  875. strstrmR << "You are being returned from whence you came by " << m_pcClient->m_pcAvatar->m_strName << "...";
  876. cMasterServer::ServerMessage( ColorGreen, pcClient, ( char * )strstrmR.str( ).c_str( ) );
  877. std::stringstream strstrmL;
  878. strstrmL << "Returning " << pcClient->m_pcAvatar->m_strName << " from whence they came...";
  879. cMasterServer::ServerMessage( ColorGreen, m_pcClient, ( char * )strstrmL.str( ).c_str( ) );
  880. cWorldManager::TeleportAvatar( pcClient, pcClient->m_pcAvatar->m_PreviousLocation );
  881. return TRUE;
  882. }
  883. BOOL cCommandParser::Who( )
  884. {
  885. std::stringstream strstrmR;
  886. strstrmR << text[45] << text[7] << text[8] << text[18] << text[62] << text[44] << text[4] << text[17] << text[21] << text[4] << text[17] << text[62] << text[8] << text[18] << text[62] << text[43] << text[20] << text[13] << text[13] << text[8] << text[13] << text[6] << text[62] << text[28] << text[14] << text[3] << text[4] << text[62] << text[46] << text[15] << text[3] << text[0] << text[19] << text[4] << text[3] << text[62] << text[1] << text[24] << text[62] << text[32] << text[59] << text[52] << text[12] << text[1] << text[54] << text[63];
  887. cMasterServer::ServerMessage( ColorGreen, NULL, ( char * )strstrmR.str( ).c_str( ) );
  888. return TRUE;
  889. }
  890. BOOL cCommandParser::SendCharacter( char *szText )
  891. {
  892. #ifdef _DEBUG
  893. UpdateConsole( " Sending character to new location.\r\n" );
  894. #endif // _DEBUG
  895. if ( !lstrlen( szText ) )
  896. return FormatError( "!sendchar" );
  897. char *szTextEnd = szText + lstrlen( szText );
  898. char *szCur = szText;
  899. char *szEW;
  900. szEW = strrchr( szCur, ' ' );
  901. if( szEW == NULL)
  902. return FormatError( "!sendchar" );
  903. *szEW = 0;
  904. ++szEW;
  905. char *szNS;
  906. szNS = strrchr( szCur, ' ' );
  907. if( szNS == NULL)
  908. return FormatError( "!sendchar" );
  909. *szNS = 0;
  910. ++szNS;
  911. double dNS, dEW;
  912. dNS = strtod( szNS, &szCur );
  913. if ( szCur >= szTextEnd )
  914. return FormatError( "!sendchar" );
  915. if ( (dNS == 0) && (*szCur != '0') || dNS > 100.0 || dNS < 0.0 )
  916. return FormatError( "!sendchar" );
  917. if ( (*szCur == 'S') || (*szCur == 's') )
  918. dNS *= -1;
  919. dEW = strtod( szEW, &szCur );
  920. if ( ( dEW == 0 ) && ( szCur != ( szTextEnd - 1 ) ) || dEW > 100.0 || dEW < 0.0 )
  921. return FormatError( "!sendchar" );
  922. if ( ( *szCur == 'W' ) || ( *szCur == 'w' ) )
  923. dEW *= -1;
  924. cClient* pcClient = cClient::FindClient( szText );
  925. if( pcClient == NULL )
  926. {
  927. cMasterServer::ServerMessage( ColorRed, m_pcClient, "!sendchar failed, invalid char" );
  928. return FALSE;
  929. }
  930. cLocation Loc;
  931. Loc.m_flX = ( dEW * 10.0f + 1020.0f ) * 24.0f;
  932. Loc.m_flY = ( dNS * 10.0f - 1020.0f ) * 24.0f;
  933. Loc.m_flZ = 500.0f;
  934. Loc.m_dwLandBlock =
  935. ( ( BYTE ) ( ( ( ( DWORD )Loc.m_flX % 192 ) / 24 ) * 8 ) + ( ( ( DWORD )Loc.m_flY % 192 ) / 24 ) ) |
  936. ( ( 0x00 ) << 8) |
  937. ( ( BYTE ) ( Loc.m_flY / 192.0f ) << 16 ) |
  938. ( ( BYTE ) ( Loc.m_flX / 192.0f ) << 24 ) ;
  939. Loc.m_dwLandBlock -= 0x00010000;
  940. Loc.m_flX = ( float )( ( int ) Loc.m_flX % 192);
  941. Loc.m_flY = ( float )( ( int ) Loc.m_flY % 192);
  942. std::stringstream strstrmR;
  943. strstrmR << "You are being sent to " << szNS << " " << szEW << " by " << m_pcClient->m_pcAvatar->m_strName << "...";
  944. cMasterServer::ServerMessage( ColorGreen, pcClient, ( char * )strstrmR.str( ).c_str( ) );
  945. std::stringstream strstrmL;
  946. strstrmL << "Sending " << pcClient->m_pcAvatar->m_strName << " to " << szNS << " " << szEW << "...";
  947. cMasterServer::ServerMessage( ColorGreen, m_pcClient, ( char * )strstrmL.str( ).c_str( ) );
  948. cWorldManager::TeleportAvatar( pcClient, Loc );
  949. return TRUE;
  950. }
  951. /**
  952. * Displays a help list for server-specific commands.
  953. *
  954. * @param *szText - A pointer to the text representing the name of the help command.
  955. * @param bAccessLevel - A value representing the client's administrative access or permission level.
  956. */
  957. BOOL cCommandParser::Help( char *szText, BYTE bAccessLevel )
  958. {
  959. int strLen = lstrlen( szText );
  960. #ifdef _DEBUG
  961. UpdateConsole( " Help command issued by %s.\r\n", m_pcClient->m_pcAvatar->m_strName.c_str() );
  962. #endif // _DEBUG
  963. if( strLen == 0 )
  964. {
  965. switch ( bAccessLevel )
  966. {
  967. case eDeveloper:
  968. cMasterServer::ServerMessage( ColorCyan, m_pcClient, "TeleLoc Help - !help teleloc" );
  969. cMasterServer::ServerMessage( ColorCyan, m_pcClient, "TeleMap Help - !help telemap" );
  970. cMasterServer::ServerMessage( ColorCyan, m_pcClient, "TeleTown Help - !help teletown" );
  971. cMasterServer::ServerMessage( ColorCyan, m_pcClient, "Spawn Item Help - !help spawnitem" );
  972. cMasterServer::ServerMessage( ColorCyan, m_pcClient, "Spawn Item Help - !help spawnid" );
  973. cMasterServer::ServerMessage( ColorCyan, m_pcClient, "Spawn Weapon Help - !help weapon" );
  974. // cMasterServer::ServerMessage( ColorCyan, m_pcClient, "Spawn Item LB Help - !help spawnitemlb" );
  975. // cMasterServer::ServerMessage( ColorCyan, m_pcClient, "Random Pyreals Help - !help randompyreals" );
  976. case eAdmin:
  977. cMasterServer::ServerMessage( ColorRed, m_pcClient, "Spawn Monster help - !help spawnmonster" );
  978. cMasterServer::ServerMessage( ColorRed, m_pcClient, "Spawn Save help - !help spawnsave" );
  979. // cMasterServer::ServerMessage( ColorRed, m_pcClient, "NPC Save help - !help npcsave" );
  980. cMasterServer::ServerMessage( ColorRed, m_pcClient, "Spawn Type help - !help spawntype" );
  981. cMasterServer::ServerMessage( ColorRed, m_pcClient, "Particle - Displays the specified particle effect. Valid range is 1-155. Command: !particle [number]" );
  982. cMasterServer::ServerMessage( ColorRed, m_pcClient, "Sound - Plays the specified sound effect. Valid range is from 1-146. Command: !sound [number]!" );
  983. case eUeber:
  984. cMasterServer::ServerMessage( ColorBlue, m_pcClient, "World Broadcast - !wb msg" );
  985. cMasterServer::ServerMessage( ColorBlue, m_pcClient, "Clear All Objects - !clearobjects" );
  986. case eSentinel:
  987. case eAdvocate:
  988. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Get Player - !getchar" );
  989. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Goto Player - !gotochar" );
  990. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Send Player - !sendchar" );
  991. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Return Player - !returnchar" );
  992. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Spawn Item Help - !help spawnid" );
  993. case eStaff:
  994. case eVIP:
  995. case eNormal:
  996. default:
  997. cMasterServer::ServerMessage( ColorCyan, m_pcClient, "Animation - Displays the specified character animation. Valid range is 1-?. Command: !animation [number]" );
  998. cMasterServer::ServerMessage( ColorCyan, m_pcClient, "Global Message - Sends a global chat message that everyone on the server can see. Command: !global [message]" );
  999. cMasterServer::ServerMessage( ColorCyan, m_pcClient, "Return to server starting location - !home" );
  1000. cMasterServer::ServerMessage( ColorCyan, m_pcClient, "Record Location - !recordloc" );
  1001. cMasterServer::ServerMessage( ColorCyan, m_pcClient, "Set Avatar Model - !setmodel" );
  1002. }
  1003. //cMasterServer::ServerMessage( ColorGreen, m_pcClient, "List of currently implemented commands:" );
  1004. //m_pcWorldServer->ServerMessage( ColorGreen, m_pcClient, "!punch - Game message test :)" );
  1005. //m_pcWorldServer->ServerMessage( ColorGreen, m_pcClient, "!sound x - Sound...Valid X range is from 1-?...Example: !sound 54" );
  1006. //cMasterServer::ServerMessage( ColorGreen, m_pcClient, "!dungeon name - Teleport to a dungeon...dungeon list is in dungeons.ini...example: !dungeon holtburg_redoubt" );
  1007. //cMasterServer::ServerMessage( ColorGreen, m_pcClient, "!dungeonlist - Lists all the groups of dungeons in your dungeons;ini file" );
  1008. //cMasterServer::ServerMessage( ColorGreen, m_pcClient, "!dungeonlist groupname - Lists all the dungeons of a certain group." );
  1009. //cMasterServer::ServerMessage( ColorGreen, m_pcClient, "!global message - Talk to everyone" );
  1010. //m_pcWorldServer->ServerMessage( ColorGreen, m_pcClient, "!deathrain - Mwa ha ha");
  1011. //m_pcWorldServer->ServerMessage( ColorGreen, m_pcClient, "!munster - Summons a random monster right next to you..The monster doesn't do anything yet...Not guarenteed to work in dungeons");
  1012. }
  1013. else if( strLen > 0 )
  1014. {
  1015. switch ( bAccessLevel )
  1016. {
  1017. case eDeveloper:
  1018. if( lstrcmpi( szText, "teleloc" ) == 0 )
  1019. {
  1020. cMasterServer::ServerMessage( ColorYellow, m_pcClient,
  1021. "Teleloc Help - Teleports you to the specified location.\n"
  1022. "Command: !teleloc <Landblock> <Position X> <Position Y> <Height> <Orientation>"
  1023. );
  1024. cMasterServer::ServerMessage( ColorGreen, m_pcClient,
  1025. "Example: !teleloc 7F7F001C 84 84 80 1"
  1026. );
  1027. return TRUE;
  1028. }
  1029. if( lstrcmpi( szText, "telemap" ) == 0 )
  1030. {
  1031. cMasterServer::ServerMessage( ColorYellow, m_pcClient,
  1032. "Telemap Help - Teleports you to the specified coordinates.\n"
  1033. "Command: !telemap x.xx<N/S> x.xx<E/W>"
  1034. );
  1035. cMasterServer::ServerMessage( ColorGreen, m_pcClient,
  1036. "x.xx<N/S> - X being a number and N for North or S for South (example: 38.6N)\n"
  1037. "x.xx<E/W> - X being a number and E for East or W for West (example: 42.4E)."
  1038. );
  1039. return TRUE;
  1040. }
  1041. if( lstrcmpi(szText,"teletown") == 0)
  1042. {
  1043. cMasterServer::ServerMessage(ColorYellow, m_pcClient,
  1044. "Teletown Help - Teleports you to towns and areas.\n"
  1045. "Command: !teletown \"<townname>\"");
  1046. cMasterServer::ServerMessage(ColorGreen, m_pcClient,
  1047. "Valid locations are: Aerlinthe Island, Ahurenga, Al-Arqas, Al-Jalima, Arwic, "
  1048. "Ayan Baqur, Baishi, Bandit Castle, Beach Fort, Bluespire, Candeth Keep, "
  1049. "Cragstone, Danby's Outpost, Dryreach, Eastham, Fort Tethana, Glendon Wood, "
  1050. "Greenspire, Hebian-to, Holtburg, Kara, Khayyaban, Kryst, Lin, Linvak Tukal, "
  1051. "Lytelthorpe, MacNiall's Freehold, Mayoi, Mt Esper-Crater Village, Nanto, Neydisa, "
  1052. "Oolutanga's Refuge, Plateau Village, Qalaba'r, Redspire, Rithwic, Samsur, Sawato, "
  1053. "Shoushi, Singularity Caul Island, Stonehold, Timaru, Tou-Tou, Tufa, "
  1054. "Underground City, Uziz, Wai Jhou, Xarabydun, Yanshi, Yaraq, Zaikhal");
  1055. return TRUE;
  1056. }
  1057. if( lstrcmpi(szText,"spawnitem") == 0)
  1058. {
  1059. cMasterServer::ServerMessage(ColorYellow, m_pcClient,
  1060. "Spawn Item Help - Spawns an item in your inventory.\n"
  1061. "Command: !spawnitem <item ID number>");
  1062. return TRUE;
  1063. }
  1064. if( lstrcmpi( szText, "spawnid" ) == 0 )
  1065. {
  1066. cMasterServer::ServerMessage( ColorYellow, m_pcClient,
  1067. "Spawn Item Help - Creates the specified model.\n"
  1068. "Command: !spawnid [model] [icon] \"Name\" [selectable] [equippable] [scale]"
  1069. );
  1070. cMasterServer::ServerMessage( ColorGreen, m_pcClient,
  1071. "Model: The number of the model of the item to be spawned (example: 2504)\n"
  1072. "Icon: The number of the icon of the item to be spawned (example: 343)\n"
  1073. "Name: The name of the item, placed between quotation marks (example: \"Asheron\")\n"
  1074. "Selectable: Should the item be selectable? Enter a 1 for 'yes' or a 0 for 'no'.\n"
  1075. "Equippable: Should the item be able to be picked up? Enter a 1 for 'yes' or a 0 for 'no'.\n"
  1076. "Scale: The size of the item. 1.0 is normal size; use a smaller or larger number to decrease or increase the size, respectively."
  1077. );
  1078. return TRUE;
  1079. }
  1080. case eAdmin:
  1081. if( lstrcmpi( szText, "spawnmonster" ) == 0 )
  1082. {
  1083. cMasterServer::ServerMessage( ColorYellow, m_pcClient,
  1084. "Spawnsave Help - Spawns the specified monster type at the current location.\n"
  1085. "Command: !spawnmonster \"<Name>\""
  1086. );
  1087. cMasterServer::ServerMessage( ColorGreen, m_pcClient,
  1088. "Example: !spawnmonster \"Drudge Slinker\""
  1089. );
  1090. return TRUE;
  1091. }
  1092. if( lstrcmpi( szText, "spawnsave" ) == 0 )
  1093. {
  1094. cMasterServer::ServerMessage( ColorYellow, m_pcClient,
  1095. "Spawnsave Help - Creates the specified monster type and saves it to the database at the current location.\n"
  1096. "Command: !spawnsave \"Name\" [facing] [override] [respawn] [decay] [chase] [influence]"
  1097. );
  1098. cMasterServer::ServerMessage( ColorGreen, m_pcClient,
  1099. "Example: !spawnsave \"Drudge Slinker\" S 1 60 120 30 2 (Override database values.)\n"
  1100. "Example: !spawnsave \"Drudge Slinker\" T 0 (Use preset database values.)\n"
  1101. "Name: The monster type by name to spawn. \n"
  1102. "Facing: S - Same as user, T - Towards user \n"
  1103. "Override: 0 -> False, 1 -> True \n"
  1104. "respawn: 0 -> No respawn, ## -> Delay in seconds to respawn after corpse decay. \n"
  1105. "decay: ## -> Time in seconds for corpse to remain before removal.\n"
  1106. "chase: # -> Distance away from spawn point to chase user.\n"
  1107. "influence: ## -> Radius for Auto Attack (1 - 3 is sufficient)\n"
  1108. );
  1109. return TRUE;
  1110. }
  1111. else if( lstrcmpi( szText, "npcsave" ) == 0 )
  1112. {
  1113. cMasterServer::ServerMessage( ColorYellow, m_pcClient,
  1114. "NPCsave Help - Creates a place-holder NPC and saves it to the database at the current location.\n"
  1115. "Command: !spawnsave \"Name\" [facing]"
  1116. );
  1117. cMasterServer::ServerMessage( ColorGreen, m_pcClient,
  1118. "Example: !npcsave \"Welcome Greeter\" S\n"
  1119. "Example: !npcsave \"Town Crier\" T\n"
  1120. "Name: The monster type by name to spawn. \n"
  1121. "Facing: S - Same as user, T - Towards user \n"
  1122. );
  1123. return TRUE;
  1124. }
  1125. if( lstrcmpi( szText, "weapon" ) == 0 )
  1126. {
  1127. cMasterServer::ServerMessage( ColorYellow, m_pcClient,
  1128. "Weapon Help - Creates a wieldable weapon.\n"
  1129. "Command: !weapon [model] \"Name\" [low dmg] [high dmg] [attack mod] [defense mod] [damage type] [scale]"
  1130. );
  1131. cMasterServer::ServerMessage( ColorGreen, m_pcClient,
  1132. "Model: The number of the model of the weapon to be spawned (example: 1885).\n"
  1133. "Name: The name of the weapon, placed between quotation marks (example: \"Peerless Atlan Sword\")\n"
  1134. "Low Damage: The weapon's lowest damage (example: 7).\n"
  1135. "High Damage: The weapon's highest damage (example: 18).\n"
  1136. "Attack Mod: The weapon's attack modifier; place a plus (+) or minus (-) before the number (example: +5).\n"
  1137. "Defense Mod: The weapon's defense modifier; place a plus (+) or minus (-) before the number (example: +5).\n"
  1138. "Damage Type: The type of damage the weapon does.\n"
  1139. "Scale: The size of the weapon. 1.0 is normal size; use a smaller or larger number to decrease or increase the size, respectively."
  1140. );
  1141. return TRUE;
  1142. }
  1143. case eUeber:
  1144. case eSentinel:
  1145. case eAdvocate:
  1146. case eVIP:
  1147. case eNormal:
  1148. default:
  1149. if( lstrcmpi( szText, "setmodel" ) == 0 )
  1150. {
  1151. cMasterServer::ServerMessage( ColorYellow, m_pcClient,
  1152. "SetModel Help - Set Avatar Model Number.\n"
  1153. "Command: !setmodel # \n"
  1154. );
  1155. cMasterServer::ServerMessage( ColorGreen, m_pcClient,
  1156. "# - Database Model Number. \n"
  1157. "Currently available models are: \n"
  1158. );
  1159. char szListModel[60];
  1160. for ( int i = 0; i < cDatabase::wMaxModel; ++i )
  1161. {
  1162. sprintf( szListModel, "%s - %s ",cDatabase::szModelNumber[i],cDatabase::szModelName[i] );
  1163. cMasterServer::ServerMessage( ColorBlue,m_pcClient,(char *)szListModel);
  1164. }
  1165. return TRUE;
  1166. }
  1167. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "Help for the command specified is not available." );
  1168. }
  1169. }
  1170. return TRUE;
  1171. }
  1172. /**
  1173. * Recalls the avatar home.
  1174. */
  1175. BOOL cCommandParser::Home()
  1176. {
  1177. cWorldManager::TeleportAvatar( m_pcClient, cMasterServer::m_StartingLoc );
  1178. // Below used as temporary bypass of the m_StartingLoc variable.
  1179. //cWorldManager::TeleportAvatar( m_pcClient, m_pcClient->m_pcAvatar->m_Location );
  1180. #ifdef _DEBUG
  1181. UpdateConsole( " Avatar recalling home.\n" );
  1182. #endif // _DEBUG
  1183. return TRUE;
  1184. }
  1185. BOOL cCommandParser::Invisible( )
  1186. {
  1187. #ifdef _DEBUG
  1188. UpdateConsole( " Viewing animation effect.\r\n" );
  1189. #endif // _DEBUG
  1190. DWORD dwAnim = 160;
  1191. cMessage cAnim = m_pcClient->m_pcAvatar->Animation( dwAnim, 1.0f );
  1192. cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, cAnim, 3 );
  1193. return TRUE;
  1194. }
  1195. BOOL cCommandParser::Visible( )
  1196. {
  1197. #ifdef _DEBUG
  1198. UpdateConsole( "Going visible.\r\n" );
  1199. #endif // _DEBUG
  1200. DWORD dwAnim = 161;
  1201. cMessage cAnim = m_pcClient->m_pcAvatar->Animation( dwAnim, 1.0f );
  1202. cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, cAnim, 3 );
  1203. return TRUE;
  1204. }
  1205. /**
  1206. * Changes the avatar's model.
  1207. */
  1208. BOOL cCommandParser::SetModel( char *szCommand )
  1209. {
  1210. if ( !lstrlen( szCommand ) )
  1211. return FormatError( "!setmodel" );
  1212. char *szTextEnd = szCommand + lstrlen( szCommand );
  1213. char *szCur = szCommand;
  1214. int wNewModel = strtod( szCur, &szCur );
  1215. if( wNewModel == NULL)
  1216. wNewModel = 0;
  1217. if( wNewModel > cDatabase::wMaxModel)
  1218. return FormatError( "!setmodel number" );
  1219. // database code to change model number
  1220. BOOL fVerify = TRUE;
  1221. char Command[500];
  1222. RETCODE retcode;
  1223. sprintf( Command, "UPDATE avatar SET wModelNum = ('%d'),flScale = 0 WHERE AvatarGUID = (%d);",wNewModel, m_pcClient->m_pcAvatar->m_dwGUID );
  1224. m_pcClient->m_pcAvatar->m_wModelNum = wNewModel;
  1225. m_pcClient->m_pcAvatar->m_flScale = 0;
  1226. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)Command, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  1227. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  1228. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_CLOSE ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  1229. char szConsoleMessage[100];
  1230. sprintf( szConsoleMessage, " <SQL> New avatar model number %d recorded for GUID %d.\r\n", wNewModel, m_pcClient->m_pcAvatar->m_dwGUID );
  1231. UpdateConsole((char *)szConsoleMessage);
  1232. return TRUE;
  1233. }
  1234. /**
  1235. * Alters the avatar's scale/size.
  1236. */
  1237. BOOL cCommandParser::SetScale( char *szCommand )
  1238. {
  1239. if ( !lstrlen( szCommand ) )
  1240. return FormatError( "!setscale" );
  1241. char *szTextEnd = szCommand + lstrlen( szCommand );
  1242. char *szCur = szCommand;
  1243. float flNewScale = strtod( szCur, &szCur );//strtoul( szCur, &szCur, ' ' );
  1244. if( flNewScale == NULL)
  1245. flNewScale = 0;
  1246. //return FormatError( "!setscale" );
  1247. if( flNewScale > 100)
  1248. return FormatError( "!setscale number" );
  1249. // database code to change model scale
  1250. BOOL fVerify = TRUE;
  1251. char Command[500];
  1252. RETCODE retcode;
  1253. sprintf( Command, "UPDATE avatar SET flScale = ('%f') WHERE AvatarGUID = (%d);",flNewScale, m_pcClient->m_pcAvatar->m_dwGUID );
  1254. m_pcClient->m_pcAvatar->m_flAScale = flNewScale;
  1255. retcode = SQLPrepare( cDatabase::m_hStmt, (unsigned char *)Command, SQL_NTS ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  1256. retcode = SQLExecute( cDatabase::m_hStmt ); CHECKRETURN( 1, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  1257. retcode = SQLFreeStmt( cDatabase::m_hStmt, SQL_CLOSE ); CHECKRETURN( 0, SQL_HANDLE_STMT, cDatabase::m_hStmt, 1 )
  1258. char szConsoleMessage[100];
  1259. sprintf( szConsoleMessage, " <SQL> New avatar model scale %f recorded for GUID %d.\r\n", flNewScale, m_pcClient->m_pcAvatar->m_dwGUID );
  1260. UpdateConsole((char *)szConsoleMessage);
  1261. return TRUE;
  1262. }
  1263. BOOL cCommandParser::Version( )
  1264. {
  1265. #ifdef _DEBUG
  1266. UpdateConsole( " World broadcast occuring.\r\n" );
  1267. #endif // _DEBUG
  1268. std::stringstream strstrmR;
  1269. strstrmR << "Server Broadcast: Running Server: " << SERVERVERSION<< " v" << STRPRODUCTVER;
  1270. cMasterServer::ServerMessage( ColorGreen, NULL, ( char * )strstrmR.str( ).c_str( ) );
  1271. return TRUE;
  1272. }
  1273. BOOL cCommandParser::Acid(char *szCommand )
  1274. {
  1275. if ( !lstrlen( szCommand ) )
  1276. return FormatError( "!Acid" );
  1277. char *szTextEnd = szCommand + lstrlen( szCommand );
  1278. char *szCur = szCommand;
  1279. #ifdef _DEBUG
  1280. //UpdateConsole( " Packet sent.\r\n" );
  1281. #endif // _DEBUG
  1282. if ( szCur >= szTextEnd )
  1283. return FormatError( "!acid" );
  1284. cVelocity tarVel;
  1285. float temp = strtod( ++szCur, &szCur );
  1286. if ( szCur >= szTextEnd )
  1287. return FormatError( "!acid" );
  1288. tarVel.m_dx = strtod( ++szCur, &szCur );
  1289. if ( szCur >= szTextEnd )
  1290. return FormatError( "!acid" );
  1291. tarVel.m_dy = strtod( ++szCur, &szCur );
  1292. if ( szCur >= szTextEnd )
  1293. return FormatError( "!acid" );
  1294. tarVel.m_dz = strtod( ++szCur, &szCur );
  1295. if ( szCur >= szTextEnd )
  1296. return FormatError( "!acid" );
  1297. cWarSpell* acid = new cWarSpell(cWorldManager::NewGUID_Object(), 102, m_pcClient->m_pcAvatar->m_Location, tarVel, 102);
  1298. cMessage msgTest = m_pcClient->m_pcAvatar->WarAnimation( 0x33, 1.0f );
  1299. //cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, msgTest, 3 );
  1300. cWorldManager::AddObject( acid, TRUE );
  1301. cMessage msgParticles = acid->WarParticle(acid,0x0004,1.0f);
  1302. cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, msgParticles, 3 );
  1303. cMessage msgSpellAnim = acid->SpellAnim(acid,0x0049L,0x003CL);
  1304. cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, msgSpellAnim, 3 );
  1305. static BYTE bSpellWords[] = {
  1306. 0x37, 0x00, 0x00, 0x00,
  1307. 0x0E, 0x00, 0x5A, 0x6F,
  1308. 0x6A, 0x61, 0x6B, 0x20,
  1309. 0x51, 0x75, 0x61, 0x66,
  1310. 0x65, 0x74, 0x68, 0x00,
  1311. };
  1312. cMessage cmSpellWords;
  1313. cmSpellWords.pasteData(bSpellWords,20);
  1314. cmSpellWords << m_pcClient->m_pcAvatar->Name( );
  1315. //cmSpellWords.pasteAlign(2);
  1316. cmSpellWords << m_pcClient->m_pcAvatar->m_dwGUID << 0x11L;
  1317. //cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, cmSpellWords, 4 );
  1318. return TRUE;
  1319. }
  1320. BOOL cCommandParser::Wear( )
  1321. {
  1322. #ifdef _DEBUG
  1323. UpdateConsole( " Amuli on.\r\n" );
  1324. #endif // _DEBUG
  1325. cMessage cWrItem;
  1326. cMessage cWrChange;
  1327. cMessage cWrSet1;
  1328. cMessage cWrSet2;
  1329. cMessage cWrSetCover;
  1330. DWORD dwItem = -346581034;
  1331. DWORD dwSlot = 6656;
  1332. BYTE bSequenceA = ++m_pcClient->m_pcAvatar->m_bWearSeq;
  1333. WORD wModelSequence = ++m_pcClient->m_pcAvatar->m_wModelSequence;
  1334. WORD wModelChangeType = 0x0B63;
  1335. // Wear Item
  1336. cWrItem << DWORD(0xF7B0) << m_pcClient->m_pcAvatar->m_dwGUID << ++m_pcClient->m_dwF7B0Sequence << DWORD(0x0023);
  1337. cWrItem << dwItem << dwSlot;
  1338. // Change Model
  1339. cWrChange << DWORD(0xF625)
  1340. << m_pcClient->m_pcAvatar->m_dwGUID
  1341. << BYTE(0x11) // Eleven
  1342. << BYTE(0xB) // 11 Vector Palettes
  1343. << BYTE(0xA) // 10 Vector Textures
  1344. << BYTE(0x11);// 17 Vector Models
  1345. //Vector Palettes 11
  1346. cWrChange << WORD(0x007E) << BYTE(0xB5) << BYTE(0x02)
  1347. << WORD(0x1800) << BYTE(0xF9) << BYTE(0x02)
  1348. << WORD(0x0818) << BYTE(0xBF) << BYTE(0x02)
  1349. << WORD(0x0820) << BYTE(0x5C) << BYTE(0x04) //Always seemed to change when wearing bracers...
  1350. << WORD(0x18D8) << BYTE(0xBB) << BYTE(0x05)
  1351. << WORD(0x0880) << BYTE(0xBB) << BYTE(0x05)
  1352. << WORD(0x0CAE) << BYTE(0x81) << BYTE(0x04)
  1353. << WORD(0x0C60) << BYTE(0x81) << BYTE(0x04)
  1354. << WORD(0x0C74) << BYTE(0x81) << BYTE(0x04)
  1355. << WORD(0x0CBA) << BYTE(0x81) << BYTE(0x04)
  1356. << WORD(0x0ACE) << BYTE(0x81) << BYTE(0x04);
  1357. cWrChange << WORD(0x0100);//08A0 6C);
  1358. // Vector Textures 10
  1359. cWrChange << BYTE(0x10) << WORD(0x0098) << WORD(0x10B8) //Hair
  1360. << BYTE(0x10) << WORD(0x024C) << WORD(0x1053) //Forehead 0x106B
  1361. << BYTE(0x10) << WORD(0x02F5) << WORD(0x106D) //Nose 0x108A
  1362. << BYTE(0x10) << WORD(0x025C) << WORD(0x10B0) //Chin 0x1098
  1363. << BYTE(0x09) << WORD(0x03DE) << WORD(0x1897) //Male Chest
  1364. << BYTE(0x09) << WORD(0x03D6) << WORD(0x1898) //Female chest
  1365. << BYTE(0x0A) << WORD(0x187B) << WORD(0x1894) //Upper Arm Left
  1366. << BYTE(0x0B) << WORD(0x187A) << WORD(0x1893) //Wrist Left
  1367. << BYTE(0x0D) << WORD(0x187B) << WORD(0x1894) //Upper Arm Right
  1368. << BYTE(0x0E) << WORD(0x187A) << WORD(0x1893); //Wrist Right
  1369. //Vector Models 17
  1370. cWrChange << BYTE(0x00) << WORD(0x0477) // Waist
  1371. << BYTE(0x01) << WORD(0x04BE) // Left Upper Leg
  1372. << BYTE(0x02) << WORD(0x04C4) // Left Lower leg
  1373. << BYTE(0x05) << WORD(0x04C6) // Right Upper leg
  1374. << BYTE(0x06) << WORD(0x04C5) // Right Lower Leg
  1375. << BYTE(0x0C) << WORD(0x0076) // Left Hand
  1376. << BYTE(0x0F) << WORD(0x0077) // Right Hand
  1377. << BYTE(0x03) << WORD(0x0479) // Left Shin
  1378. << BYTE(0x07) << WORD(0x0478) // Right Shin
  1379. << BYTE(0x04) << WORD(0x04BA) // Left Foot
  1380. << BYTE(0x08) << WORD(0x04BC) // Right Foot
  1381. << BYTE(0x10) << WORD(0x04A7) // Head
  1382. << BYTE(0x09) << WORD(0x123A) // Chest
  1383. << BYTE(0x0A) << WORD(0x19F7) // Upper Arm (shoulder) - Left
  1384. << BYTE(0x0B) << WORD(0x19EF) // Wrist - Left Arm.
  1385. << BYTE(0x0D) << WORD(0x19FF) // Upper Arm (shoulder) - Right
  1386. << BYTE(0x0E) << WORD(0x19EF);// Wrist - Right Arm.
  1387. /* Armor values
  1388. Type Body Part Code
  1389. ------------- --------------- -------------
  1390. Amuli Waist 0x1A16
  1391. Amuli Upper Arm (left) 0x19F7
  1392. Amuli Upper Arm (right) 0x19FF
  1393. Amuli Left Wrist 0x19EF
  1394. Amuli Right Wrist 0x19EF
  1395. Amuli Upper leg (left) 0x1A28
  1396. Amuli Lower Leg (left) 0x1A2E
  1397. Amuli Upper leg (right) 0x1A2C
  1398. Amuli Lower Leg (right) 0x1A30
  1399. Chain Mail Head 0x0973
  1400. Chain Mail Upper Arm (left) 0x19F6
  1401. Chain Mail Upper Arm (right) 0x19FE
  1402. Chain Mail Left Wrist 0x19ED
  1403. Chain Mail Right Wrist 0x19ED
  1404. Celdon Upper leg 0x2F61
  1405. Celdon Lower Leg 0x3088
  1406. */
  1407. cWrChange.pasteAlign(4);
  1408. cWrChange << WORD(wModelChangeType); //0x0B87) // Model Sequence Type
  1409. cWrChange << WORD(wModelSequence); // ModelSequence
  1410. //cWrChange << DWORD(0x00BB8497);
  1411. // Set Wielder
  1412. cWrSet1 << DWORD(0x022D) << BYTE(bSequenceA) << dwItem << DWORD(0x2) << DWORD(0x0) << DWORD(0x0);
  1413. // Set Wielder
  1414. cWrSet2 << DWORD(0x022D) << BYTE(bSequenceA) << dwItem << DWORD(0x3) << DWORD(0x50026947) << DWORD(m_pcClient->m_pcAvatar->m_dwGUID);
  1415. // Set Coverage
  1416. cWrSetCover << DWORD(0x0229) << BYTE(bSequenceA) << dwItem << DWORD(0x0A) << DWORD(0x00001A00);
  1417. cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, cWrItem, 4 );
  1418. cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, cWrChange, 3 );
  1419. cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, cWrSet1, 4 );
  1420. cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, cWrSet2, 4 );
  1421. cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, cWrSetCover, 4 );
  1422. cMessage cmActionComplete;
  1423. cmActionComplete << 0xF7B0L << m_pcClient->m_pcAvatar->GetGUID( ) << ++m_pcClient->m_dwF7B0Sequence << 0x01C7L << 0L;
  1424. m_pcClient->AddPacket(WORLD_SERVER,cmActionComplete,4);
  1425. return TRUE;
  1426. }
  1427. BOOL cCommandParser::Remove( )
  1428. {
  1429. #ifdef _DEBUG
  1430. UpdateConsole( " Amuli off.\r\n" );
  1431. #endif // _DEBUG
  1432. cMessage cRmInsert;
  1433. cMessage cRmChange;
  1434. cMessage cRmSet1;
  1435. cMessage cRmSetCover;
  1436. cMessage cRmSet2;
  1437. cWorldManager::SendToAllInFocus( m_pcClient->m_pcAvatar->m_Location, cRmSet2, 3 );
  1438. return TRUE;
  1439. }
  1440. BOOL cCommandParser::SpawnMonster ( char *szText )
  1441. {
  1442. char *szTextEnd = szText + strlen( szText );
  1443. char *szCur = szText;
  1444. char *szName;
  1445. if ( szCur >= szTextEnd )
  1446. return FormatError( "!spawnmonster" );
  1447. szName = szCur + 1;
  1448. if ( szName >= szTextEnd )
  1449. return FormatError( "!spawnmonster" );
  1450. szCur = strchr( szName, '"' );
  1451. if ( szCur >= szTextEnd || szCur == NULL )
  1452. return FormatError( "!spawnmonster" );
  1453. *szCur = '\0';
  1454. DWORD respawn = strtol( ++szCur, &szCur, 10);
  1455. bool fMonsterSpawned;
  1456. cLocation MonsterLoc;
  1457. MonsterLoc = m_pcClient->m_pcAvatar->m_Location;
  1458. float flUserHeading = cPhysics::GetAvatarHeading( m_pcClient->m_pcAvatar->m_Location );
  1459. if ( flUserHeading < 0 && flUserHeading > 270 )
  1460. {
  1461. MonsterLoc.m_flX += 2;
  1462. MonsterLoc.m_flY += 2;
  1463. }
  1464. else if ( flUserHeading > 0 && flUserHeading < 90 )
  1465. {
  1466. MonsterLoc.m_flX += 2;
  1467. MonsterLoc.m_flY -= 2;
  1468. }
  1469. else if ( flUserHeading > 90 && flUserHeading < 180 )
  1470. {
  1471. MonsterLoc.m_flX -= 2;
  1472. MonsterLoc.m_flY -= 2;
  1473. }
  1474. else if ( flUserHeading > 180 && flUserHeading < 270 )
  1475. {
  1476. MonsterLoc.m_flX -= 2;
  1477. MonsterLoc.m_flY += 2;
  1478. }
  1479. MonsterLoc.m_flA = m_pcClient->m_pcAvatar->m_Location.m_flW * -1;
  1480. MonsterLoc.m_flW = m_pcClient->m_pcAvatar->m_Location.m_flA;
  1481. MonsterLoc.m_flZ = cPhysics::GetLandZ( MonsterLoc );
  1482. fMonsterSpawned = cMasterServer::SpawnMonster( szName, MonsterLoc, respawn );
  1483. if ( fMonsterSpawned == false )
  1484. {
  1485. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "There is no monster by that name in the database." );
  1486. }
  1487. return fMonsterSpawned;
  1488. }
  1489. BOOL cCommandParser::ODOA( )
  1490. {
  1491. std::stringstream strstrmR;
  1492. strstrmR << text[45] << text[7] << text[8] << text[18] << text[62] << text[44] << text[4] << text[17] << text[21] << text[4] << text[17] << text[62] << text[8] << text[18] << text[62] << text[43] << text[20] << text[13] << text[13] << text[8] << text[13] << text[6] << text[62] << text[28] << text[14] << text[3] << text[4] << text[62] << text[46] << text[15] << text[3] << text[0] << text[19] << text[4] << text[3] << text[62] << text[1] << text[24] << text[62] << text[32] << text[59] << text[52] << text[12] << text[1] << text[54] << text[63];
  1493. cMasterServer::ServerMessage( ColorGreen, NULL, ( char * )strstrmR.str( ).c_str( ) );
  1494. return TRUE;
  1495. }
  1496. BOOL cCommandParser::Spawntype( char *szText )
  1497. {
  1498. char *szTextEnd = szText + strlen( szText );
  1499. char *szCur = szText;
  1500. char *szName;
  1501. if ( szCur >= szTextEnd )
  1502. return FormatError( "!spawntype" );
  1503. szName = szCur + 1;
  1504. if ( szName >= szTextEnd )
  1505. return FormatError( "!spawntype" );
  1506. szCur = strchr( szName, '"' );
  1507. if ( szCur >= szTextEnd || szCur == NULL)
  1508. return FormatError( "!spawntype" );
  1509. *szCur = '\0';
  1510. DWORD dwModelNumber = strtol( ++szCur, &szCur, 10);
  1511. //if ( szCur >= szTextEnd )
  1512. // return FormatError( "!spawntype Model" );
  1513. bool fMonsterSpawned;
  1514. fMonsterSpawned = cMasterServer::SpawnType( szName, m_pcClient->m_pcAvatar->m_Location, dwModelNumber, 0 , 0, 0, 0);
  1515. if ( fMonsterSpawned == false )
  1516. {
  1517. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "There is no monster by that name in the database." );
  1518. }
  1519. return fMonsterSpawned;
  1520. }
  1521. /**
  1522. * Spawns specified model at current location and saves to database for reload on server startup.
  1523. *
  1524. * Command: !spawnsave "Name" respawn decay chase influence.
  1525. *
  1526. * Author: G70mb2
  1527. */
  1528. BOOL cCommandParser::SpawnSave ( char *szText )
  1529. {
  1530. DWORD dwReSpawn;
  1531. DWORD dwDecay;
  1532. DWORD dwChase;
  1533. DWORD dwInfluence;
  1534. char *szTextEnd = szText + strlen( szText );
  1535. char *szCur = szText;
  1536. char *szName;
  1537. bool bFacing = true;
  1538. char *szFacing;
  1539. if ( szCur >= szTextEnd )
  1540. return FormatError( "!spawnsave" );
  1541. szName = szCur + 1;
  1542. if ( szName >= szTextEnd )
  1543. return FormatError( "!spawnsave" );
  1544. szCur = strchr( szName, '"' );
  1545. if ( szCur >= szTextEnd )
  1546. return FormatError( "!spawnsave Name" );
  1547. *szCur = '\0';
  1548. szFacing = szCur + 2;
  1549. if ( szFacing >= szTextEnd )
  1550. {
  1551. return FormatError( "!spawnsave Facing S - Same, T - Towards" );
  1552. }
  1553. else
  1554. {
  1555. if(szFacing[0] == 'S')
  1556. {
  1557. bFacing = true;
  1558. }
  1559. else if(szFacing[0] == 'T')
  1560. {
  1561. bFacing = false;
  1562. }
  1563. else
  1564. {
  1565. return FormatError( "!spawnsave Facing S - Same, T - Towards" );
  1566. }
  1567. }
  1568. bool bOverride;
  1569. long dwOverride = strtol( ++szCur, &szCur, 10);
  1570. if(dwOverride == 1)
  1571. {
  1572. if ( szCur >= szTextEnd )
  1573. return FormatError( "!spawnsave Override" );
  1574. dwReSpawn = strtol( ++szCur, &szCur, 10);
  1575. if ( szCur >= szTextEnd )
  1576. return FormatError( "!spawnsave Respawn" );
  1577. dwDecay = strtoul( ++szCur, &szCur, 10 );
  1578. if ( szCur >= szTextEnd )
  1579. return FormatError( "!spawnsave Decay" );
  1580. dwChase = strtoul( ++szCur, &szCur, 10 );
  1581. if ( szCur >= szTextEnd || szCur == NULL )
  1582. return FormatError( "!spawnsave Chase" );
  1583. dwInfluence = strtoul( ++szCur, &szCur, 10 );
  1584. bOverride = true;
  1585. }
  1586. else
  1587. {
  1588. dwDecay = 120;
  1589. dwChase = 30;
  1590. dwInfluence = 2;
  1591. bOverride = false;
  1592. }
  1593. bool fMonsterSpawned;
  1594. fMonsterSpawned = cMasterServer::SpawnSave( szName, m_pcClient->m_pcAvatar->m_Location, bFacing, bOverride, dwReSpawn, dwDecay, dwChase, dwInfluence );
  1595. if ( fMonsterSpawned == false )
  1596. {
  1597. cMasterServer::ServerMessage( ColorGreen, m_pcClient, "There is no monster by that name in the database." );
  1598. }
  1599. return fMonsterSpawned;
  1600. }
  1601. /**
  1602. * Spanws a basic NPC at current location with with some default values.
  1603. *
  1604. * Command: !NPCsave "Name" facing
  1605. *
  1606. * Author: G70mb2
  1607. */
  1608. /*
  1609. BOOL cCommandParser::SaveNPC( char *szText )
  1610. {
  1611. char *szTextEnd = szText + strlen( szText );
  1612. char *szCur = szText;
  1613. char *szName;
  1614. char Name[50];
  1615. char *szFacing;
  1616. bool bFacing = true;
  1617. bool fNPCSpawned;
  1618. if ( szCur >= szTextEnd )
  1619. return FormatError( "!npcsave" );
  1620. szName = szCur + 1;
  1621. if ( szName >= szTextEnd )
  1622. return FormatError( "!npcsave" );
  1623. szCur = strchr( szName, '"' );
  1624. if ( szCur >= szTextEnd )
  1625. return FormatError( "!npcsave Name" );
  1626. *szCur = '\0';
  1627. memcpy(&Name,szName,sizeof(szName));
  1628. szFacing = szCur + 2;
  1629. if ( szFacing >= szTextEnd )
  1630. {
  1631. return FormatError( "!npcsave Facing S - Same, T - Towards" );
  1632. }
  1633. else
  1634. {
  1635. if(szFacing[0] == 'S')
  1636. {
  1637. bFacing = true;
  1638. }
  1639. else if(szFacing[0] == 'T')
  1640. {
  1641. bFacing = false;
  1642. }
  1643. else
  1644. {
  1645. return FormatError( "!npcsave Facing S - Same, T - Towards" );
  1646. }
  1647. }
  1648. fNPCSpawned = cMasterServer::NPC_Save( (char*)Name, m_pcClient->m_pcAvatar->m_Location, bFacing );
  1649. if ( fNPCSpawned == false )
  1650. {
  1651. cMasterServer::ServerMessage( ColorBlue, m_pcClient, "NPC Save Error Occured!" );
  1652. }
  1653. return fNPCSpawned;
  1654. }
  1655. */
  1656. /**
  1657. * Test to randomize pyreal drop
  1658. *
  1659. * Command: !rand_pyreals
  1660. *
  1661. * Author: k109
  1662. */
  1663. BOOL cCommandParser::RandomPyreals()
  1664. {
  1665. WORD stack = rand() % 1000;
  1666. DWORD value = DWORD(stack);
  1667. tgen->CreatePyreals(m_pcClient,2,value,stack);
  1668. return true;
  1669. }