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

ClientCommands.cpp 47KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999
  1. #include "StdAfx.h"
  2. #include "Client.h"
  3. #include "ClientEvents.h"
  4. #include "ClientCommands.h"
  5. #include "PhysicsObj.h"
  6. #include "Monster.h"
  7. #include "Player.h"
  8. #include "Door.h"
  9. #include "Item.h"
  10. #include "Network.h"
  11. #include "World.h"
  12. #include "ChatMsgs.h"
  13. #include "Portal.h"
  14. #include "Database2.h"
  15. #include "GameMode.h"
  16. #include "Lifestone.h"
  17. // Most of these commands are just for experimenting and never meant to be used in a real game
  18. // TODO: Add flags to these commands so they are only accessible under certain modes such as a sandbox mode
  19. CommandMap CommandBase::m_mCommands;
  20. void CommandBase::Create(const char* szName, const char* szArguments, const char* szHelp, pfnCommandCallback pCallback, int iAccessLevel, bool bSource)
  21. {
  22. CommandEntry i =
  23. {
  24. szName,
  25. szArguments,
  26. szHelp,
  27. pCallback,
  28. iAccessLevel,
  29. bSource
  30. };
  31. m_mCommands[std::string(szName)] = i;
  32. }
  33. bool g_bSilence = false;
  34. bool SpawningEnabled(CBasePlayer *pPlayer)
  35. {
  36. if (g_bSilence)
  37. {
  38. if (pPlayer->GetClient()->GetAccessLevel() < ADMIN_ACCESS)
  39. {
  40. return false;
  41. }
  42. }
  43. return true;
  44. }
  45. CLIENT_COMMAND(myloc, "", "Info on your current location.", BASIC_ACCESS)
  46. {
  47. const char* szResponse =
  48. csprintf("%08X %.2f %.2f %.2f %.2f %.2f %.2f %.2f",
  49. pPlayer->m_Origin.landcell,
  50. pPlayer->m_Origin.x, pPlayer->m_Origin.y, pPlayer->m_Origin.z,
  51. pPlayer->m_Angles.w, pPlayer->m_Angles.x, pPlayer->m_Angles.y, pPlayer->m_Angles.z);
  52. pPlayer->SendText(szResponse, 1);
  53. return false;
  54. }
  55. CLIENT_COMMAND(startgame, "[gameid]", "Spawns something by name (right now works for monsters, NPCs, players.)", ADMIN_ACCESS)
  56. {
  57. if (argc < 1)
  58. return true;
  59. int game = atoi(argv[0]);
  60. switch (game)
  61. {
  62. case 0:
  63. g_pWorld->SetNewGameMode(NULL);
  64. break;
  65. case 1:
  66. g_pWorld->SetNewGameMode(new CGameMode_Tag());
  67. break;
  68. }
  69. return false;
  70. }
  71. CLIENT_COMMAND(spawnportal, "", "Spawns a dysfunctional portal near you.", BASIC_ACCESS)
  72. {
  73. if (!SpawningEnabled(pPlayer))
  74. {
  75. return false;
  76. }
  77. CPortal *pPortal = new CPortal();
  78. pPortal->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  79. pPortal->m_Origin = pPlayer->m_Origin;
  80. pPortal->m_Origin.x += 20.0f;
  81. pPortal->m_Angles = pPlayer->m_Angles;
  82. g_pWorld->CreateEntity(pPortal);
  83. return false;
  84. }
  85. CLIENT_COMMAND(spawndoor, "", "Spawns a door at your location.", BASIC_ACCESS)
  86. {
  87. if (!SpawningEnabled(pPlayer))
  88. {
  89. return false;
  90. }
  91. CPhysicsObj *pDoor = new CBaseDoor();
  92. pDoor->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  93. pDoor->m_Origin = pPlayer->m_Origin;
  94. pDoor->m_Angles = pPlayer->m_Angles;
  95. g_pWorld->CreateEntity(pDoor);
  96. return false;
  97. }
  98. CLIENT_COMMAND(global, "<text> [color=1]", "Displays text globally.", ADMIN_ACCESS)
  99. {
  100. if (argc < 1)
  101. {
  102. return true;
  103. }
  104. if (g_bSilence)
  105. {
  106. return false;
  107. }
  108. const char* szText = argv[0];
  109. long lColor = (argc >= 2) ? atoi(argv[1]) : 1;
  110. g_pWorld->BroadcastGlobal(ServerText(szText, lColor), PRIVATE_MSG);
  111. return false;
  112. }
  113. CLIENT_COMMAND(animationall, "<num> [speed]", "Performs an animation for everyone.", ADMIN_ACCESS)
  114. {
  115. if (argc < 1)
  116. {
  117. return true;
  118. }
  119. WORD wIndex = atoi(argv[0]);
  120. float fSpeed = (argc >= 2) ? (float)atof(argv[1]) : 1.0f;
  121. float fDelay = 0.5f;
  122. PlayerMap *pPlayers = g_pWorld->GetPlayers();
  123. for (PlayerMap::iterator i = pPlayers->begin(); i != pPlayers->end(); i++)
  124. {
  125. i->second->Animation_PlayPrimary(wIndex, fSpeed, fDelay);
  126. }
  127. return false;
  128. }
  129. CLIENT_COMMAND(freezeall, "", "Freezes or unfreezes everyone.", ADMIN_ACCESS)
  130. {
  131. if (argc < 1)
  132. {
  133. return true;
  134. }
  135. PlayerMap *pPlayers = g_pWorld->GetPlayers();
  136. for (PlayerMap::iterator i = pPlayers->begin(); i != pPlayers->end(); i++)
  137. {
  138. i->second->ChangeVIS(i->second->m_PhysicsState ^ (DWORD)(FROZEN_PS));
  139. }
  140. return false;
  141. }
  142. CLIENT_COMMAND(lineall, "", "Moves everyone.", ADMIN_ACCESS)
  143. {
  144. loc_t loc = pPlayer->m_Origin;
  145. heading_t angles = pPlayer->m_Angles;
  146. PlayerMap *pPlayers = g_pWorld->GetPlayers();
  147. for (PlayerMap::iterator i = pPlayers->begin(); i != pPlayers->end(); i++)
  148. {
  149. if (i->second != pPlayer)
  150. {
  151. loc.x += 1.5f;
  152. i->second->SendText("Teleporting you...", 1);
  153. i->second->Movement_Teleport(loc, angles);
  154. }
  155. }
  156. return false;
  157. }
  158. CLIENT_COMMAND(effect, "<index> [scale=1]", "Emits a particle effect.", BASIC_ACCESS)
  159. {
  160. if (argc < 1)
  161. return true;
  162. DWORD dwIndex;
  163. float flScale;
  164. dwIndex = atol(argv[0]);
  165. if (argc >= 2) flScale = (float)atof(argv[1]);
  166. else flScale = (float)1.0f;
  167. pPlayer->EmitEffect(dwIndex, flScale);
  168. return false;
  169. }
  170. CLIENT_COMMAND(sound, "<index> [speed?=1]", "Emits a sound effect.", BASIC_ACCESS)
  171. {
  172. if (argc < 1)
  173. return true;
  174. DWORD dwIndex = atol(argv[0]);
  175. float flSpeed = (float)((argc >= 2) ? atof(argv[1]) : 1.0f);
  176. pPlayer->EmitSound(dwIndex, flSpeed);
  177. return false;
  178. }
  179. CLIENT_COMMAND(arwic, "", "Teleports you to Arwic.", BASIC_ACCESS)
  180. {
  181. loc_t origin(0xC6A90023, 102.4f, 70.1f, 44.0f);
  182. heading_t angles(0.70710677f, 0, 0, 0.70710677f);
  183. pPlayer->SendText("Teleporting you to Arwic..", 1);
  184. pPlayer->Movement_Teleport(origin, angles);
  185. return false;
  186. }
  187. CLIENT_COMMAND(removethis, "", "Removes an object.", BASIC_ACCESS)
  188. {
  189. std::string itemRemoved = pPlayer->RemoveLastAssessed();
  190. if (itemRemoved != "") {
  191. pPlayer->SendText(std::string("Removed object: ").append(itemRemoved).c_str(),1);
  192. }
  193. else
  194. {
  195. pPlayer->SendText(std::string("Please assess a valid object you wish to clear!").append(itemRemoved).c_str(), 1);
  196. return true;
  197. }
  198. return false;
  199. }
  200. CLIENT_COMMAND(tele, "<player name>", "Teleports you to a player.", BASIC_ACCESS)
  201. {
  202. if (argc < 1)
  203. return true;
  204. CBasePlayer *Target = g_pWorld->FindPlayer(argv[0]);
  205. if (Target)
  206. {
  207. pPlayer->SendText(csprintf("Teleporting to %s ..", argv[0]), 1);
  208. pPlayer->Movement_Teleport(Target->m_Origin, Target->m_Angles);
  209. }
  210. else
  211. pPlayer->SendText(csprintf("Couldn't find player \"%s\" ?", argv[0]), 1);
  212. return false;
  213. }
  214. CLIENT_COMMAND(teleall, "<target>", "Teleports all players target. If no target specified, teleports to you.", ADMIN_ACCESS)
  215. {
  216. CBasePlayer* target;
  217. if (argc < 1)
  218. target = pPlayer;
  219. else {
  220. target = g_pWorld->FindPlayer(argv[0]);
  221. if (target == NULL)
  222. {
  223. pPlayer->SendText("Invalid target!",1);
  224. return true;
  225. }
  226. }
  227. PlayerMap* map = g_pWorld->GetPlayers();
  228. PlayerMap::iterator pit = map->begin();
  229. PlayerMap::iterator pend = map->end();
  230. //This is probably really bad..
  231. bool teleportedOne = false;
  232. while (pit != pend)
  233. {
  234. CBasePlayer *them = pit->second;
  235. if (them != target)
  236. {
  237. teleportedOne = true;
  238. pPlayer->SendText(std::string("Teleported: ").append(them->GetName()).c_str(), 1);
  239. them->Movement_Teleport(target->m_Origin, target->m_Angles);
  240. them->SendText(std::string("Teleported by: ").append(pPlayer->GetName()).c_str(), 1);
  241. }
  242. pit++;
  243. }
  244. if (teleportedOne)
  245. return false;
  246. else
  247. {
  248. pPlayer->SendText("Didn't teleport anyone! Nobody on server?",1);
  249. }
  250. return true;
  251. }
  252. CLIENT_COMMAND(teletown, "<town name>", "Teleports you to a town.", BASIC_ACCESS)
  253. {
  254. if (argc == 0) {
  255. pPlayer->SendText("Your teleporting choices are:", 1);
  256. pPlayer->SendText(g_pWorld->GetTeleportList().c_str(), 1);
  257. return true;
  258. }
  259. std::string cmdString = argv[0];
  260. for (int i = 1; i < argc; i++)
  261. {
  262. cmdString.append(" ");
  263. cmdString.append(argv[i]);
  264. }
  265. TeleTownList_s var = g_pWorld->GetTeleportLocation(cmdString);
  266. if (var.m_teleString != "")
  267. {
  268. pPlayer->SendText(std::string("Portaling To: ").append(var.m_teleString).c_str(), 1);
  269. pPlayer->Movement_Teleport(var.loc, var.heading);
  270. return false;
  271. }
  272. else
  273. pPlayer->SendText("Town Not Found! Try again...", 1);
  274. return true;
  275. }
  276. CLIENT_COMMAND(teleto, "<coords>", "Teleports you to coordinates.", BASIC_ACCESS)
  277. {
  278. if (argc < 2)
  279. return true;
  280. float NS = NorthSouth(argv[0]);
  281. float EW = EastWest(argv[1]);
  282. char cNS = ' ';
  283. char cEW = ' ';
  284. if (NS < 0) cNS = 'S'; else if (NS > 0) cNS = 'N';
  285. if (EW < 0) cEW = 'W'; else if (EW > 0) cEW = 'E';
  286. loc_t origin = GetLocation(NS, EW);
  287. heading_t angles;
  288. if (!origin.landcell)
  289. {
  290. pPlayer->SendText("Bad coordinate location!", 1);
  291. }
  292. else if (IsWaterBlock(origin.landcell))
  293. {
  294. pPlayer->SendText("Bad location! That's a water block, dummy!", 1);
  295. }
  296. else
  297. {
  298. char* szTP = csprintf("Teleporting to %0.1f%c %0.1f%c (Cell: %08X Z: %.1f)", fabs(NS), cNS, fabs(EW), cEW, origin.landcell, origin.z);
  299. pPlayer->SendText(szTP, 1);
  300. pPlayer->Movement_Teleport(origin, angles);
  301. }
  302. return false;
  303. }
  304. CLIENT_COMMAND(spawnbox, "", "Spawns a box.", BASIC_ACCESS)
  305. {
  306. if (!SpawningEnabled(pPlayer))
  307. {
  308. return false;
  309. }
  310. CPhysicsObj *pTurbineBox = new CPhysicsObj();
  311. pTurbineBox->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  312. pTurbineBox->m_Origin.landcell = pPlayer->GetLandcell();
  313. pTurbineBox->m_Origin.x = pPlayer->m_Origin.x + 1.0f;
  314. pTurbineBox->m_Origin.y = pPlayer->m_Origin.y;
  315. pTurbineBox->m_Origin.z = pPlayer->m_Origin.z + 4.0f;
  316. g_pWorld->CreateEntity(pTurbineBox);
  317. return 0;
  318. }
  319. CLIENT_COMMAND(spawnboxes, "", "Spawns 50 boxes. For load testing.", BASIC_ACCESS)
  320. {
  321. if (!SpawningEnabled(pPlayer))
  322. {
  323. return false;
  324. }
  325. for (int i = 0; i < 50; i++)
  326. {
  327. CPhysicsObj *pTurbineBox = new CPhysicsObj();
  328. pTurbineBox->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  329. pTurbineBox->m_Origin.landcell = pPlayer->GetLandcell();
  330. pTurbineBox->m_Origin.x = pPlayer->m_Origin.x + RandomFloat(0, 30);
  331. pTurbineBox->m_Origin.y = pPlayer->m_Origin.y + RandomFloat(0, 30);
  332. pTurbineBox->m_Origin.z = 0;
  333. g_pWorld->CreateEntity(pTurbineBox);
  334. }
  335. return 0;
  336. }
  337. CLIENT_COMMAND(spawndoors, "", "Spawns doors at holtburg west.", BASIC_ACCESS)
  338. {
  339. if (!SpawningEnabled(pPlayer))
  340. {
  341. return false;
  342. }
  343. CPhysicsObj *pDoor1 = new CBaseDoor();
  344. pDoor1->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  345. CPhysicsObj *pDoor2 = new CBaseDoor();
  346. pDoor2->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  347. CPhysicsObj *pDoor3 = new CBaseDoor();
  348. pDoor3->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  349. CPhysicsObj *pDoor4 = new CBaseDoor();
  350. pDoor4->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  351. CPhysicsObj *pDoor5 = new CBaseDoor();
  352. pDoor5->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  353. pDoor1->SetLocation(0xA5B4003C, 174.3589935f, 77.19989777f, 46.08199692f);
  354. pDoor1->SetAngles(1.0f, 0.0f, 0.0f, 0.0f);
  355. pDoor2->SetLocation(0xA9B0000F, 36.34f, 150.33f, 58.081997f);
  356. pDoor2->SetAngles(1.0f, 0.0f, 0.0f, 0.0f);
  357. pDoor3->SetLocation(0xA9B0000F, 29.780001f, 158.07001f, 58.081997f);
  358. pDoor3->SetAngles(0.70339513f, 0.0f, 0.0f, -0.7107991f);
  359. pDoor4->SetLocation(0xA9B0010D, 37.759998f, 107.05f, 64.082001f);
  360. pDoor4->SetAngles(-0.70710677f, 0.0f, 0.0f, -0.70710677f);
  361. pDoor5->SetLocation(0xA9B00007, 12.7549f, 150.343f, 58.081997f);
  362. pDoor5->SetAngles(-0.70710677f, 0.0f, 0.0f, -0.70710677f);
  363. g_pWorld->CreateEntity(pDoor1);
  364. g_pWorld->CreateEntity(pDoor2);
  365. g_pWorld->CreateEntity(pDoor3);
  366. g_pWorld->CreateEntity(pDoor4);
  367. g_pWorld->CreateEntity(pDoor5);
  368. return 0;
  369. }
  370. CLIENT_COMMAND(vismode, "<mode>", "Changes your physics state.", BASIC_ACCESS)
  371. {
  372. if (argc < 1)
  373. return true;
  374. pPlayer->ChangeVIS(strtoul(argv[0], NULL, 16));
  375. return false;
  376. }
  377. CLIENT_COMMAND(spawnbael, "", "Spawns Bael'Zharon.", BASIC_ACCESS)
  378. {
  379. if (!SpawningEnabled(pPlayer))
  380. {
  381. return false;
  382. }
  383. CBaelZharon *pBael = new CBaelZharon();
  384. pBael->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  385. pBael->m_Origin.landcell = pPlayer->GetLandcell();
  386. pBael->m_Origin.x = pPlayer->m_Origin.x;
  387. pBael->m_Origin.y = pPlayer->m_Origin.y;
  388. pBael->m_Origin.z = pPlayer->m_Origin.z + 10;
  389. g_pWorld->CreateEntity(pBael);
  390. return false;
  391. }
  392. extern double g_TimeAdjustment;
  393. CLIENT_COMMAND(timeadjust, "", "Time adjustment Careful.", ADMIN_ACCESS)
  394. {
  395. if (argc < 1)
  396. return true;
  397. g_TimeAdjustment = atof(argv[0]);
  398. return false;
  399. }
  400. CLIENT_COMMAND(squelchall, "", "Squelch all.", ADMIN_ACCESS)
  401. {
  402. if (argc < 1)
  403. return true;
  404. g_bSilence = atoi(argv[0]) ? true : false;
  405. if (g_bSilence)
  406. pPlayer->SendText("Silenced all players and spawning.", 1);
  407. else
  408. pPlayer->SendText("Unsilenced all players and spawning.", 1);
  409. return false;
  410. }
  411. CLIENT_COMMAND(spawnrabbit, "", "Spawns a rabbit.", BASIC_ACCESS)
  412. {
  413. if (!SpawningEnabled(pPlayer))
  414. {
  415. return false;
  416. }
  417. CBaseMonster *pRabbit = new CBaseMonster();
  418. pRabbit->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  419. pRabbit->m_Origin = pPlayer->m_Origin;
  420. pRabbit->m_Origin.z += 20.0;
  421. pRabbit->m_dwAnimationSet = 0x09000062;
  422. pRabbit->m_dwSoundSet = 0x2000003D;
  423. pRabbit->m_dwEffectSet = 0x3400002D;
  424. pRabbit->m_dwModel = 0x0200047B;
  425. pRabbit->m_fScale = 7.0f;
  426. pRabbit->m_strName = "Big White Rabbit";
  427. pRabbit->m_miBaseModel.SetBasePalette(0x01B4);
  428. pRabbit->m_miBaseModel.ReplacePalette(0x09AA, 0x00, 0x00);
  429. g_pWorld->CreateEntity(pRabbit);
  430. return false;
  431. }
  432. CLIENT_COMMAND(targetdrudge, "", "Spawns a Target Drudge.", BASIC_ACCESS)
  433. {
  434. if (!SpawningEnabled(pPlayer))
  435. {
  436. return false;
  437. }
  438. CTargetDrudge *pDrudge = new CTargetDrudge();
  439. pDrudge->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  440. pDrudge->m_Origin.landcell = pPlayer->GetLandcell();
  441. pDrudge->m_Origin.x = pPlayer->m_Origin.x;
  442. pDrudge->m_Origin.y = pPlayer->m_Origin.y;
  443. pDrudge->m_Origin.z = pPlayer->m_Origin.z + 10;
  444. g_pWorld->CreateEntity(pDrudge);
  445. return false;
  446. }
  447. CLIENT_COMMAND(spawnwand, "", "Spawns a wand.", BASIC_ACCESS)
  448. {
  449. if (!SpawningEnabled(pPlayer))
  450. {
  451. return false;
  452. }
  453. CBaseWand* pWand = new CBaseWand();
  454. pWand->m_dwGUID = g_pWorld->GenerateGUID(eItemGUID);
  455. pWand->m_Origin.landcell = pPlayer->GetLandcell();
  456. pWand->m_Origin.x = pPlayer->m_Origin.x;
  457. pWand->m_Origin.y = pPlayer->m_Origin.y;
  458. pWand->m_Origin.z = pPlayer->m_Origin.z;
  459. g_pWorld->CreateEntity(pWand);
  460. return false;
  461. }
  462. CLIENT_COMMAND(teleloc, "<landcell> [x=0] [y=0] [z=0]", "Teleports to a specific location.", BASIC_ACCESS)
  463. {
  464. if (argc < 1)
  465. return false;
  466. loc_t origin;
  467. heading_t angles = pPlayer->m_Angles;
  468. origin.landcell = strtoul(argv[0], NULL, 16);
  469. origin.x = (float)((argc >= 2) ? atof(argv[1]) : 0);
  470. origin.y = (float)((argc >= 3) ? atof(argv[2]) : 0);
  471. origin.z = (float)((argc >= 4) ? atof(argv[3]) : 0);
  472. //angles.w = 1.0f;
  473. //angles.x = 0;
  474. //angles.y = 0;
  475. //angles.z = 0;
  476. pPlayer->Movement_Teleport(origin, angles);
  477. return false;
  478. }
  479. CLIENT_COMMAND(spawnmodel, "<model index> [scale=1] [name=*]", "Spawns a model.", BASIC_ACCESS)
  480. {
  481. if (argc < 1)
  482. {
  483. return true;
  484. }
  485. if (!SpawningEnabled(pPlayer))
  486. {
  487. return false;
  488. }
  489. DWORD dwModel = strtoul(argv[0], NULL, 16);
  490. if (!(dwModel & 0xFF000000))
  491. dwModel |= 0x02000000;
  492. float flScale = (float)((argc >= 2) ? atof(argv[1]) : 1.0f);
  493. const char* szName = (argc >= 3) ? argv[2] : csprintf("Model #%08X", dwModel);
  494. CPhysicsObj *pSpawn = new CPhysicsObj();
  495. pSpawn->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  496. pSpawn->m_dwModel = dwModel;
  497. pSpawn->m_ItemType = TYPE_GEM;
  498. pSpawn->m_fScale = flScale;
  499. pSpawn->m_strName = szName;
  500. pSpawn->m_Origin.landcell = pPlayer->GetLandcell();
  501. pSpawn->m_Origin.x = pPlayer->m_Origin.x;
  502. pSpawn->m_Origin.y = pPlayer->m_Origin.y;
  503. pSpawn->m_Origin.z = pPlayer->m_Origin.z;
  504. g_pWorld->CreateEntity(pSpawn);
  505. pSpawn->SetDescription(csprintf("This model was spawned by %s.\nModel #: %08X\nScale: %f\n", pPlayer->GetName(), dwModel, flScale));
  506. return false;
  507. }
  508. CLIENT_COMMAND(spawnmodels, "<start index> <end index>", "Spawns a range of models.", BASIC_ACCESS)
  509. {
  510. if (argc < 2)
  511. {
  512. return true;
  513. }
  514. DWORD dwModelStart = strtoul(argv[0], NULL, 16);
  515. if (!(dwModelStart & 0xFF000000))
  516. dwModelStart |= 0x02000000;
  517. DWORD dwModelEnd = strtoul(argv[1], NULL, 16);
  518. if (!(dwModelEnd & 0xFF000000))
  519. dwModelEnd |= 0x02000000;
  520. if (dwModelStart > dwModelEnd && dwModelStart != 0)
  521. {
  522. return true;
  523. }
  524. DWORD dwCount = (dwModelEnd - dwModelStart) + 1;
  525. DWORD dwWidth = (int)sqrt((double)dwCount);
  526. if ((dwModelEnd - dwModelStart) >= 50)
  527. {
  528. return true;
  529. }
  530. if (!SpawningEnabled(pPlayer))
  531. {
  532. return false;
  533. }
  534. int x = 0;
  535. int y = 0;
  536. for (DWORD i = dwModelStart; i <= dwModelEnd; i++)
  537. {
  538. CPhysicsObj *pSpawn = new CPhysicsObj();
  539. pSpawn->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  540. pSpawn->m_dwModel = i;
  541. pSpawn->m_ItemType = TYPE_GEM;
  542. pSpawn->m_fScale = 1.0f;
  543. pSpawn->m_strName = csprintf("Model #%08X", i);;
  544. pSpawn->m_Origin.landcell = pPlayer->GetLandcell();
  545. pSpawn->m_Origin.x = pPlayer->m_Origin.x + (x * 10.0f);
  546. pSpawn->m_Origin.y = pPlayer->m_Origin.y + (y * 10.0f);
  547. pSpawn->m_Origin.z = pPlayer->m_Origin.z;
  548. pSpawn->SetDescription(csprintf("This model was spawned by %s.\nModel #: %08X", pPlayer->GetName(), i));
  549. g_pWorld->CreateEntity(pSpawn);
  550. if (x == dwWidth)
  551. {
  552. x = 0;
  553. y += 1;
  554. }
  555. else
  556. x++;
  557. }
  558. return false;
  559. }
  560. CLIENT_COMMAND(spawnmonster2, "<model index> <base palette>", "Spawns a monster.", BASIC_ACCESS)
  561. {
  562. if (argc < 3)
  563. {
  564. return true;
  565. }
  566. if (!SpawningEnabled(pPlayer))
  567. {
  568. return false;
  569. }
  570. DWORD dwModel = strtoul(argv[0], NULL, 16);
  571. if (!(dwModel & 0xFF000000))
  572. dwModel |= 0x02000000;
  573. DWORD dwPalette1 = strtoul(argv[1], NULL, 16);
  574. DWORD dwPalette2 = strtoul(argv[2], NULL, 16);
  575. dwPalette1 &= 0xFFFFF;
  576. dwPalette2 &= 0xFFFFF;
  577. CBaseMonster *pSpawn = new CBaseMonster();
  578. pSpawn->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  579. pSpawn->m_dwModel = dwModel;
  580. pSpawn->m_fScale = 1.0f;
  581. pSpawn->m_strName = csprintf("0x%X 0x%X 0x%X", dwModel, dwPalette1, dwPalette2);
  582. pSpawn->m_Origin.landcell = pPlayer->GetLandcell();
  583. pSpawn->m_Origin.x = pPlayer->m_Origin.x;
  584. pSpawn->m_Origin.y = pPlayer->m_Origin.y;
  585. pSpawn->m_Origin.z = pPlayer->m_Origin.z;
  586. pSpawn->m_miBaseModel.dwBasePalette = dwPalette1;
  587. pSpawn->m_miBaseModel.lPalettes.push_back(PaletteRpl(dwPalette2, 0, 0));
  588. g_pWorld->CreateEntity(pSpawn);
  589. pSpawn->SetDescription(csprintf("This monster was spawned by %s.\nModel #: %08X\nPalette #: %08X %08X\n", pPlayer->GetName(), dwModel, dwPalette1, dwPalette2));
  590. pSpawn->PostSpawn();
  591. return false;
  592. }
  593. CLIENT_COMMAND(spawnmonster, "<model index> [scale=1] [name=*] [dotcolor]", "Spawns a monster.", BASIC_ACCESS)
  594. {
  595. if (argc < 1)
  596. {
  597. return true;
  598. }
  599. if (!SpawningEnabled(pPlayer))
  600. {
  601. return false;
  602. }
  603. DWORD dwModel = strtoul(argv[0], NULL, 16);
  604. if (!(dwModel & 0xFF000000))
  605. dwModel |= 0x02000000;
  606. float flScale = (float)((argc >= 2) ? atof(argv[1]) : 1.0f);
  607. const char* szName = (argc >= 3) ? argv[2] : csprintf("Model #%08X", dwModel);
  608. int dotColor = (int)((argc >= 4) ? atoi(argv[3]) : 0);
  609. CBaseMonster *pSpawn = new CBaseMonster();
  610. pSpawn->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  611. pSpawn->m_dwModel = dwModel;
  612. pSpawn->m_fScale = flScale;
  613. pSpawn->m_strName = szName;
  614. pSpawn->m_Origin.landcell = pPlayer->GetLandcell();
  615. pSpawn->m_Origin.x = pPlayer->m_Origin.x;
  616. pSpawn->m_Origin.y = pPlayer->m_Origin.y;
  617. pSpawn->m_Origin.z = pPlayer->m_Origin.z;
  618. pSpawn->m_BlipColor = dotColor;
  619. g_pWorld->CreateEntity(pSpawn);
  620. pSpawn->SetDescription(csprintf("This monster was spawned by %s.\nModel #: %08X\nScale: %f\n", pPlayer->GetName(), dwModel, flScale));
  621. pSpawn->PostSpawn();
  622. return false;
  623. }
  624. CLIENT_COMMAND(spawnitem, "<model index> [scale=1] [name=*]", "Spawns an item.", BASIC_ACCESS)
  625. {
  626. if (argc < 1)
  627. {
  628. return true;
  629. }
  630. if (!SpawningEnabled(pPlayer))
  631. {
  632. return false;
  633. }
  634. DWORD dwModel = strtoul(argv[0], NULL, 16);
  635. if (!(dwModel & 0xFF000000))
  636. dwModel |= 0x02000000;
  637. float flScale = (float)((argc >= 2) ? atof(argv[1]) : 1.0f);
  638. const char* szName = (argc >= 3) ? argv[2] : csprintf("Model #%08X", dwModel);
  639. CBaseItem *pSpawn = new CBaseItem();
  640. pSpawn->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  641. pSpawn->m_dwModel = dwModel;
  642. pSpawn->m_fScale = flScale;
  643. pSpawn->m_strName = szName;
  644. pSpawn->m_Origin.landcell = pPlayer->GetLandcell();
  645. pSpawn->m_Origin.x = pPlayer->m_Origin.x;
  646. pSpawn->m_Origin.y = pPlayer->m_Origin.y;
  647. pSpawn->m_Origin.z = pPlayer->m_Origin.z;
  648. g_pWorld->CreateEntity(pSpawn);
  649. pSpawn->SetDescription(csprintf("This item was spawned by %s.\nModel #: %08X\nScale: %f\n", pPlayer->GetName(), dwModel, flScale));
  650. return false;
  651. }
  652. CLIENT_COMMAND(spawnlifestone, "", "Spawns a lifestone.", BASIC_ACCESS)
  653. {
  654. CBaseLifestone *pSpawn = new CBaseLifestone();
  655. pSpawn->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  656. pSpawn->m_Origin.landcell = pPlayer->GetLandcell();
  657. pSpawn->m_Origin.x = pPlayer->m_Origin.x;
  658. pSpawn->m_Origin.y = pPlayer->m_Origin.y;
  659. pSpawn->m_Origin.z = pPlayer->m_Origin.z;
  660. g_pWorld->CreateEntity(pSpawn);
  661. pSpawn->SetDescription(csprintf("Life Stone spawned by %s.", pPlayer->GetName()));
  662. return false;
  663. }
  664. CLIENT_COMMAND(clearspawns, "", "Clears the spawns in your current landblock", BASIC_ACCESS)
  665. {
  666. CLandBlock *pBlock = pPlayer->GetBlock();
  667. if (pBlock)
  668. pBlock->ClearSpawns();
  669. pPlayer->SendText("Clearing spawns in your landblock.", 1);
  670. return false;
  671. }
  672. CLIENT_COMMAND(clearallspawns, "", "Clears all spawns in all landblocks (slow.)", ADMIN_ACCESS)
  673. {
  674. g_pWorld->ClearAllSpawns();
  675. pPlayer->SendText("Clearing spawns in all landblocks.", 1);
  676. return false;
  677. }
  678. SERVER_COMMAND(kick, "<player name>", "Kicks the specified player.", ADMIN_ACCESS)
  679. {
  680. if (argc < 1)
  681. return true;
  682. if (pPlayer)
  683. {
  684. LOG(Command, Normal, "\"%s\" is using the kick command.\n", pPlayer->GetName());
  685. }
  686. else
  687. {
  688. LOG(Command, Normal, "Server is using the kick command.\n");
  689. }
  690. CBasePlayer *pTarget = g_pWorld->FindPlayer(argv[0]);
  691. if (pTarget)
  692. g_pNetwork->KickClient(pTarget->GetClient());
  693. else
  694. pPlayer->SendText("Couldn't find target player.", 1);
  695. return false;
  696. }
  697. /*
  698. CLIENT_COMMAND(AddSpellByID, "id", "Adds a spell by ID", ADMIN_ACCESS)
  699. {
  700. if (argc < 1)
  701. return true;
  702. int id = atoi(argv[0]);
  703. pPlayer->AddSpellByID(id);
  704. return false;
  705. }
  706. */
  707. CLIENT_COMMAND(test, "<index>", "Performs the specified test.", BASIC_ACCESS)
  708. {
  709. if (argc < 1)
  710. {
  711. return true;
  712. }
  713. if (!SpawningEnabled(pPlayer))
  714. {
  715. return false;
  716. }
  717. DWORD dwCell = pPlayer->GetLandcell();
  718. float x = pPlayer->m_Origin.x;
  719. float y = pPlayer->m_Origin.y;
  720. float z = pPlayer->m_Origin.z;
  721. switch (atoi(argv[0]))
  722. {
  723. case 1: {
  724. float goodZ = CalcSurfaceZ(dwCell, x, y);
  725. const char* text = csprintf("CalcZ: %f PlayerZ: %f", goodZ, z);
  726. pPlayer->SendText(text, 1);
  727. break;
  728. }
  729. case 2: {
  730. CBaseItem *pSpawn = new CAcademyCoat();
  731. pSpawn->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  732. pSpawn->m_Origin.landcell = dwCell;
  733. pSpawn->m_Origin.x = x;
  734. pSpawn->m_Origin.y = y;
  735. pSpawn->m_Origin.z = z;
  736. g_pWorld->CreateEntity(pSpawn);
  737. BinaryWriter* co = pSpawn->CreateMessage();
  738. //OutputConsoleBytes(co->GetData(), co->GetSize());
  739. delete co;
  740. break;
  741. }
  742. case 3: {
  743. CBaseItem *pSpawn = new CBoboHelm();
  744. pSpawn->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  745. pSpawn->m_Origin.landcell = dwCell;
  746. pSpawn->m_Origin.x = x;
  747. pSpawn->m_Origin.y = y;
  748. pSpawn->m_Origin.z = z;
  749. g_pWorld->CreateEntity(pSpawn);
  750. BinaryWriter* co = pSpawn->CreateMessage();
  751. //OutputConsoleBytes(co->GetData(), co->GetSize());
  752. delete co;
  753. break;
  754. }
  755. case 4: {
  756. CBaseItem *pSpawn = new CPhatRobe();
  757. pSpawn->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  758. pSpawn->m_Origin.landcell = dwCell;
  759. pSpawn->m_Origin.x = x;
  760. pSpawn->m_Origin.y = y;
  761. pSpawn->m_Origin.z = z;
  762. g_pWorld->CreateEntity(pSpawn);
  763. BinaryWriter* co = pSpawn->CreateMessage();
  764. //OutputConsoleBytes(co->GetData(), co->GetSize());
  765. delete co;
  766. break;
  767. }
  768. case 5: {
  769. CBaseItem *pSpawn = new CEnvoyShield();
  770. pSpawn->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  771. pSpawn->m_Origin.landcell = dwCell;
  772. pSpawn->m_Origin.x = x;
  773. pSpawn->m_Origin.y = y;
  774. pSpawn->m_Origin.z = z;
  775. g_pWorld->CreateEntity(pSpawn);
  776. BinaryWriter* co = pSpawn->CreateMessage();
  777. //OutputConsoleBytes(co->GetData(), co->GetSize());
  778. delete co;
  779. break;
  780. }
  781. case 6: {
  782. if (argc < 3)
  783. break;
  784. DWORD start = strtoul(argv[1], 0, 16);
  785. DWORD end = strtoul(argv[2], 0, 16);
  786. if (start < 0)
  787. start = 0;
  788. if (start > 0xFF)
  789. start = 0xFF;
  790. if (end < start)
  791. end = start;
  792. if (end > 0xFF)
  793. end = 0xFF;
  794. CBaseArmor *pSpawn = new CPhatRobe();
  795. pSpawn->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  796. pSpawn->m_Origin.landcell = dwCell;
  797. pSpawn->m_Origin.x = x;
  798. pSpawn->m_Origin.y = y;
  799. pSpawn->m_Origin.z = z;
  800. pSpawn->m_miWornModel.lPalettes.clear();
  801. pSpawn->m_miWornModel.lPalettes.push_back(PaletteRpl(0x137F, (BYTE)start, (BYTE)(end - start)));
  802. g_pWorld->CreateEntity(pSpawn);
  803. BinaryWriter* co = pSpawn->CreateMessage();
  804. //OutputConsoleBytes(co->GetData(), co->GetSize());
  805. delete co;
  806. break;
  807. }
  808. case 7: {
  809. if (argc < 3)
  810. break;
  811. DWORD start = strtoul(argv[1], 0, 16);
  812. DWORD end = strtoul(argv[2], 0, 16);
  813. if (start < 0)
  814. start = 0;
  815. if (start > 0xFF)
  816. start = 0xFF;
  817. if (end < start)
  818. end = start;
  819. if (end > 0xFF)
  820. end = 0xFF;
  821. CPhysicsObj *pTarget = g_pWorld->FindWithinPVS(pPlayer, pPlayer->m_LastAssessed);
  822. if (pTarget)
  823. {
  824. pTarget->m_miBaseModel.lPalettes.clear();
  825. pTarget->m_miBaseModel.lPalettes.push_back(PaletteRpl(0x137F, (BYTE)start, (BYTE)(end - start)));
  826. pTarget->UpdateModel();
  827. }
  828. break;
  829. }
  830. }
  831. return false;
  832. }
  833. CLIENT_COMMAND(spelltest, "", "Performs a spell test.", BASIC_ACCESS)
  834. {
  835. if (!SpawningEnabled(pPlayer))
  836. {
  837. return false;
  838. }
  839. //E0 and E1 are cool spellcasting animations
  840. //136 = moooooo
  841. //const char* text;
  842. //text = csprintf("Running spelltest..");
  843. //SendText(text, 1);
  844. if (pPlayer->m_wStance != 0x49)
  845. return false;
  846. pPlayer->SpawnCows();
  847. return false;
  848. }
  849. CLIENT_COMMAND(animation, "<index> [speed=1]", "Plays a primary animation.", BASIC_ACCESS)
  850. {
  851. if (argc < 1)
  852. return true;
  853. WORD wIndex = atoi(argv[0]);
  854. float fSpeed = (argc >= 2) ? (float)atof(argv[1]) : 1.0f;
  855. float fDelay = 0.5f;
  856. pPlayer->Animation_PlayPrimary(wIndex, fSpeed, fDelay);
  857. ANIMATIONSET* pPlayerSet = g_pPortal->GetAnimationSet(0x09000001);
  858. if (pPlayerSet) {
  859. //AnimationEntry* pEntry = pPlayerSet->LookupAnimation(pPlayer->m_wStance, wIndex);
  860. //if (!pEntry)
  861. // pPlayer->SendText("Animation index unknown to server.", 1);
  862. //else
  863. // pPlayer->SendText(csprintf("AnimationID: %08X", pEntry->m_dwAnimID), 1);
  864. }
  865. return false;
  866. }
  867. /*
  868. CLIENT_COMMAND(setmodel, "<model>", "Allows you to set your model", BASIC_ACCESS)
  869. {
  870. if (argc < 1)
  871. return true;
  872. WORD wIndex = atoi(argv[0]);
  873. pPlayer->m_dwModel = 0x02000000 + wIndex;
  874. pPlayer->UpdateModel();
  875. return false;
  876. }
  877. */
  878. CLIENT_COMMAND(setmodel, "[monster]", "Changes your model to a monster.", BASIC_ACCESS)
  879. {
  880. if (!SpawningEnabled(pPlayer))
  881. {
  882. return false;
  883. }
  884. if (argc < 1)
  885. {
  886. return true;
  887. }
  888. CCapturedWorldObjectInfo *pMonsterInfo = g_pGameDatabase->GetCapturedMonsterData(argv[0]);
  889. if (!pMonsterInfo)
  890. {
  891. pPlayer->SendText("Couldn't find that monster!", 1);
  892. return false;
  893. }
  894. float fScale = 1.0f;
  895. if (argc >= 2)
  896. {
  897. fScale = (float)atof(argv[1]);
  898. if (fScale < 0.01)
  899. fScale = 0.01f;
  900. if (fScale > 1000.0)
  901. fScale = 1000;
  902. }
  903. pPlayer->m_miBaseModel = pMonsterInfo->appearance;
  904. pPlayer->m_dwModel = pMonsterInfo->physics.setup_id;
  905. pPlayer->m_dwAnimationSet = pMonsterInfo->physics.mtable_id;
  906. pPlayer->m_dwSoundSet = pMonsterInfo->physics.stable_id;
  907. pPlayer->m_dwEffectSet = pMonsterInfo->physics.phstable_id;
  908. pPlayer->m_fScale = pMonsterInfo->physics.object_scale * fScale;
  909. pPlayer->UpdateEntity(pPlayer);
  910. return false;
  911. }
  912. CLIENT_COMMAND(invisible, "", "Go Invisible", BASIC_ACCESS)
  913. {
  914. float fSpeed = (argc >= 2) ? (float)atof(argv[1]) : 1.0f;
  915. pPlayer->Animation_PlayPrimary(160, fSpeed, 0.5f);
  916. return false;
  917. }
  918. CLIENT_COMMAND(visible, "", "Go Visible", BASIC_ACCESS)
  919. {
  920. float fSpeed = (argc >= 2) ? (float)atof(argv[1]) : 1.0f;
  921. pPlayer->Animation_PlayPrimary(161, fSpeed, 0.5f);
  922. return false;
  923. }
  924. CLIENT_COMMAND(motion, "<index> [speed=1]", "Plays a sequenced animation.", BASIC_ACCESS)
  925. {
  926. if (argc < 1)
  927. return true;
  928. WORD wIndex = atoi(argv[0]);
  929. float fSpeed = (argc >= 2) ? (float)atof(argv[1]) : 1.0f;
  930. pPlayer->Animation_PlaySimpleAnimation(wIndex, fSpeed);
  931. return false;
  932. }
  933. void SendDungeonInfo(CBasePlayer* pPlayer, DungeonDesc_t* pInfo)
  934. {
  935. pPlayer->SendText(csprintf("Information for ID %04X:", pInfo->wBlockID), 1);
  936. pPlayer->SendText(csprintf("Name: %s\nAuthor: %s\nDescription: %s", pInfo->szDungeonName, pInfo->szAuthor, pInfo->szDescription), 1);
  937. }
  938. void SendDungeonInfo(CBasePlayer* pPlayer, WORD wBlockID)
  939. {
  940. DungeonDesc_t* pInfo = g_pWorld->GetDungeonDesc(wBlockID);
  941. if (!pInfo)
  942. {
  943. if (!g_pWorld->DungeonExists(wBlockID))
  944. pPlayer->SendText("Whatchoo' talk bout willis? (That's not a dungeon.)", 1);
  945. else
  946. pPlayer->SendText("That dungeon has not been described.", 1);
  947. }
  948. else
  949. SendDungeonInfo(pPlayer, pInfo);
  950. }
  951. CLIENT_COMMAND(dungeon, "<command>", "Dungeon commands.", BASIC_ACCESS)
  952. {
  953. if (argc < 1)
  954. return true;
  955. if (!stricmp(argv[0], "help"))
  956. {
  957. if (argc < 2)
  958. {
  959. pPlayer->SendText("Dungeon commands:", 1);
  960. pPlayer->SendText("@dungeon help [command]\n@dungeon info [block/name]\n@dungeon list\n@dungeon random\n@dungeon search <substring>\n@dungeon set <name>\n@dungeon tele <block/name>\n@dungeon unknown", 1);
  961. return false;
  962. }
  963. if (!stricmp(argv[1], "info"))
  964. {
  965. pPlayer->SendText("@dungeon info - Retrieves information about your current dungeon.", 1);
  966. pPlayer->SendText("@dungeon info [block] - Retrieves dungeon information using a hex BlockID.", 1);
  967. pPlayer->SendText("@dungeon info [name] - Retrieves dungeon information by name.", 1);
  968. }
  969. else if (!stricmp(argv[1], "list"))
  970. pPlayer->SendText("@dungeon list - Displays a list of named dungeons.", 1);
  971. else if (!stricmp(argv[1], "set"))
  972. pPlayer->SendText("@dungeon set <name> - Sets your current dungeon's name, and its drop point.", 1);
  973. else if (!stricmp(argv[1], "tele"))
  974. {
  975. pPlayer->SendText("@dungeon tele <block> - Teleports to a dungeon by BlockID.", 1);
  976. pPlayer->SendText("@dungeon tele <name> - Teleports to a dungeon by name.", 1);
  977. }
  978. else if (!stricmp(argv[1], "unknown"))
  979. pPlayer->SendText("@dungeon unknown - List of unnamed dungeon BlockIDs.", 1);
  980. else if (!stricmp(argv[1], "random"))
  981. pPlayer->SendText("@dungeon random - Teleports you to a random dungeon.", 1);
  982. else if (!stricmp(argv[1], "search"))
  983. pPlayer->SendText("@dungeon search <substring> - Searchs for dungeon names that contain the substring.", 1);
  984. else
  985. pPlayer->SendText("Unknown @dungeon command. Type @dungeon help for a list of valid choices.", 1);
  986. return false;
  987. }
  988. else if (!stricmp(argv[0], "unknown"))
  989. {
  990. LocationMap* pDungeons = g_pWorld->GetDungeons();
  991. LocationMap::iterator i = pDungeons->begin();
  992. LocationMap::iterator e = pDungeons->end();
  993. DWORD dwCount = 0;
  994. std::string UnkList = "Unknown Dungeons:\n";
  995. while (i != e)
  996. {
  997. //DWORD dwCell = i->first;
  998. WORD wBlockID = BLOCK_WORD(i->first);
  999. if (!g_pWorld->GetDungeonDesc(wBlockID))
  1000. {
  1001. UnkList += csprintf("%04X, ", wBlockID);
  1002. dwCount++;
  1003. }
  1004. i++;
  1005. }
  1006. UnkList += csprintf("\nEnd of Unknown Dungeons (%lu unknown)", dwCount);
  1007. pPlayer->SendText(UnkList.c_str(), 1);
  1008. }
  1009. else if (!stricmp(argv[0], "tele"))
  1010. {
  1011. if (argc < 2)
  1012. return true;
  1013. if (strlen(argv[1]) < 6)
  1014. {
  1015. //by ID
  1016. WORD wBlockID = (WORD)strtoul(argv[1], NULL, 16);
  1017. bool forceFindDrop = false;
  1018. if (argc >= 3)
  1019. {
  1020. forceFindDrop = atoi(argv[2]) ? true : false;
  1021. }
  1022. if (!wBlockID)
  1023. {
  1024. pPlayer->SendText("Bad block ID. Please use a valid hex value.", 1);
  1025. return false;
  1026. }
  1027. DungeonDesc_t* pInfo = g_pWorld->GetDungeonDesc(wBlockID);
  1028. if (!pInfo || forceFindDrop)
  1029. {
  1030. if (!g_pWorld->DungeonExists(wBlockID))
  1031. pPlayer->SendText("That dungeon doesn't exist!", 1);
  1032. else
  1033. {
  1034. loc_t result = g_pWorld->FindDungeonDrop(wBlockID);
  1035. if (!result.landcell)
  1036. pPlayer->SendText("Couldn't find a drop zone there.", 1);
  1037. else
  1038. {
  1039. pPlayer->SendText(csprintf("Teleporting you to BlockID %04X ..", wBlockID), 1);
  1040. pPlayer->Movement_Teleport(result, pPlayer->m_Angles);
  1041. }
  1042. }
  1043. }
  1044. else
  1045. {
  1046. pPlayer->SendText(csprintf("Teleporting you to %s (%04X) ..", pInfo->szDungeonName, pInfo->wBlockID), 1);
  1047. pPlayer->Movement_Teleport(pInfo->origin, pInfo->angles);
  1048. }
  1049. }
  1050. else
  1051. {
  1052. //by name
  1053. const char* szName = argv[1];
  1054. DungeonDesc_t* pInfo = g_pWorld->GetDungeonDesc(szName);
  1055. if (pInfo)
  1056. {
  1057. pPlayer->SendText(csprintf("Teleporting you to %s (%04X) ..", pInfo->szDungeonName, pInfo->wBlockID), 1);
  1058. pPlayer->Movement_Teleport(pInfo->origin, pInfo->angles);
  1059. }
  1060. else
  1061. pPlayer->SendText("There is no dungeon by that name. Use @dungeon list for named dungeons. Remember to use quotes.", 1);
  1062. }
  1063. }
  1064. else if (!stricmp(argv[0], "set"))
  1065. {
  1066. if (argc < 2)
  1067. return true;
  1068. DWORD dwCell = pPlayer->GetLandcell();
  1069. if (CELL_WORD(dwCell) < 0xFF) {
  1070. pPlayer->SendText("Go inside first, silly!", 1);
  1071. return false;
  1072. }
  1073. if (strlen(argv[1]) < 6) {
  1074. pPlayer->SendText("Please enter a name of at least 6 characters in length.", 1);
  1075. return false;
  1076. }
  1077. if (strlen(argv[1]) > 80) {
  1078. pPlayer->SendText("Please enter a shorter name.", 1);
  1079. return false;
  1080. }
  1081. time_t ltime = time(NULL);
  1082. tm* tptr = localtime(&ltime);
  1083. char* szTime;
  1084. if (tptr)
  1085. {
  1086. szTime = asctime(tptr);
  1087. szTime[strlen(szTime) - 1] = 0; //Remove \n
  1088. }
  1089. else
  1090. szTime = "???";
  1091. WORD wBlockID = BLOCK_WORD(dwCell);
  1092. const char* szName = argv[1];
  1093. const char* szAuthor = pPlayer->GetName();
  1094. const char* szDescription = csprintf("Recorded %s", szTime);
  1095. g_pWorld->SetDungeonDesc(wBlockID, szName, szAuthor, szDescription, pPlayer->m_Origin, pPlayer->m_Angles);
  1096. pPlayer->SendText(csprintf("Dungeon information set. (%04X = \"%s\")", wBlockID, szName), 1);
  1097. }
  1098. else if (!stricmp(argv[0], "info"))
  1099. {
  1100. if (argc < 2)
  1101. {
  1102. DWORD dwCell = pPlayer->GetLandcell();
  1103. if (CELL_WORD(dwCell) < 0xFF) {
  1104. pPlayer->SendText("Go inside first, silly!", 1);
  1105. return false;
  1106. }
  1107. SendDungeonInfo(pPlayer, BLOCK_WORD(dwCell));
  1108. return false;
  1109. }
  1110. if (strlen(argv[1]) < 6)
  1111. {
  1112. //by ID
  1113. WORD wBlockID = (WORD)strtoul(argv[1], NULL, 16);
  1114. if (!wBlockID)
  1115. {
  1116. pPlayer->SendText("Bad block ID. Please use a valid hex value. Remember to use quotes around names!", 1);
  1117. return false;
  1118. }
  1119. SendDungeonInfo(pPlayer, wBlockID);
  1120. }
  1121. else
  1122. {
  1123. //by name
  1124. const char* szName = argv[1];
  1125. DungeonDesc_t* pInfo = g_pWorld->GetDungeonDesc(szName);
  1126. if (pInfo)
  1127. SendDungeonInfo(pPlayer, pInfo);
  1128. else
  1129. pPlayer->SendText("There is no dungeon by that name. Use @dungeon list for named dungeons. Use quotes around names.", 1);
  1130. }
  1131. }
  1132. else if (!stricmp(argv[0], "list"))
  1133. {
  1134. DungeonDescMap* pDDs = g_pWorld->GetDungeonDescs();
  1135. DungeonDescMap::iterator i = pDDs->begin();
  1136. DungeonDescMap::iterator e = pDDs->end();
  1137. std::string DL = "Dungeon List:";
  1138. while (i != e)
  1139. {
  1140. DL += csprintf("\n%04X - %s", i->second.wBlockID, i->second.szDungeonName);
  1141. i++;
  1142. }
  1143. DL += csprintf("\nEnd of Dungeon List (%lu named dungeons)", (DWORD)pDDs->size());
  1144. pPlayer->SendText(DL.c_str(), 1);
  1145. }
  1146. else if (!stricmp(argv[0], "search"))
  1147. {
  1148. if ((argc < 2) || (strlen(argv[1]) <= 0))
  1149. {
  1150. pPlayer->SendText("You must enter a search string.", 1);
  1151. return 0;
  1152. }
  1153. DungeonDescMap* pDDs = g_pWorld->GetDungeonDescs();
  1154. DungeonDescMap::iterator i = pDDs->begin();
  1155. DungeonDescMap::iterator e = pDDs->end();
  1156. DWORD dwCount = 0;
  1157. std::string DL = "Dungeon Matches:";
  1158. while (i != e)
  1159. {
  1160. static char szDungeonName[100];
  1161. strncpy(szDungeonName, i->second.szDungeonName, 100);
  1162. if (strstr(strlwr(szDungeonName), strlwr(argv[1])))
  1163. {
  1164. DL += csprintf("\n%04X - %s", i->second.wBlockID, i->second.szDungeonName);
  1165. dwCount++;
  1166. }
  1167. i++;
  1168. }
  1169. DL += csprintf("\nEnd of List (%lu matches)", dwCount);
  1170. pPlayer->SendText(DL.c_str(), 1);
  1171. }
  1172. else if (!stricmp(argv[0], "random"))
  1173. {
  1174. loc_t result = g_pWorld->FindDungeonDrop();
  1175. heading_t angles = pPlayer->m_Angles;
  1176. if (!result.landcell)
  1177. {
  1178. pPlayer->SendText("No dungeons to teleport to.", 1);
  1179. }
  1180. else
  1181. {
  1182. WORD wBlockID = BLOCK_WORD(result.landcell);
  1183. DungeonDesc_t* pDD;
  1184. if (pDD = g_pWorld->GetDungeonDesc(wBlockID))
  1185. {
  1186. pPlayer->SendText(csprintf("Teleporting you to %s ..", pDD->szDungeonName), 1);
  1187. result = pDD->origin;
  1188. angles = pDD->angles;
  1189. }
  1190. else
  1191. pPlayer->SendText("Teleporting you to a random dungeon..", 1);
  1192. pPlayer->Movement_Teleport(result, angles);
  1193. }
  1194. }
  1195. else
  1196. return true;
  1197. return false;
  1198. }
  1199. CLIENT_COMMAND(player, "<command>", "Player commands.", BASIC_ACCESS)
  1200. {
  1201. if (argc < 1)
  1202. return 1;
  1203. if (!stricmp(argv[0], "help"))
  1204. {
  1205. if (argc < 2)
  1206. {
  1207. pPlayer->SendText("Player commands:", 1);
  1208. pPlayer->SendText("@player help [command]\n@player info <name>\n@player list\n@player tele <name>", 1);
  1209. return false;
  1210. }
  1211. if (!stricmp(argv[1], "info"))
  1212. pPlayer->SendText("@player info <name> - Retrieves information on a player, by name.", 1);
  1213. else if (!stricmp(argv[1], "list"))
  1214. pPlayer->SendText("@player list - Displays a list of players currently logged in.", 1);
  1215. else if (!stricmp(argv[1], "tele"))
  1216. {
  1217. pPlayer->SendText("@player tele <name> - Teleports to a player by name.", 1);
  1218. pPlayer->SendText("NOTE: This is the same as the @tele command.", 1);
  1219. }
  1220. else
  1221. pPlayer->SendText("Unknown @player command. Type @player help for a list of valid choices.", 1);
  1222. return false;
  1223. }
  1224. else if (!stricmp(argv[0], "tele"))
  1225. {
  1226. pPlayer->SendText("NOTE: Use @tele instead. ;)", 1);
  1227. tele(pPlayer, &argv[1], argc - 1);
  1228. }
  1229. else if (!stricmp(argv[0], "info"))
  1230. {
  1231. if (argc < 2)
  1232. return true;
  1233. CBasePlayer *pPlayer = g_pWorld->FindPlayer(argv[1]);
  1234. if (!pPlayer)
  1235. pPlayer->SendText(csprintf("Couldn't find player \"%s\"", argv[1]), 1);
  1236. else
  1237. {
  1238. const char* info = csprintf(
  1239. "Player Info:\nGUID: 0x%08X\nName: %s\nLocation: %08X %.1f %.1f %.1f",
  1240. pPlayer->m_dwGUID, pPlayer->GetName(), pPlayer->GetLandcell(),
  1241. pPlayer->m_Origin.x, pPlayer->m_Origin.y, pPlayer->m_Origin.z);
  1242. pPlayer->SendText(info, 1);
  1243. }
  1244. }
  1245. else if (!stricmp(argv[0], "list"))
  1246. {
  1247. PlayerMap *pPlayers = g_pWorld->GetPlayers();
  1248. std::string strPlayerList = "Player List:";
  1249. for (PlayerMap::iterator i = pPlayers->begin(); i != pPlayers->end(); i++)
  1250. {
  1251. strPlayerList += "\n";
  1252. strPlayerList += i->second->GetName();
  1253. }
  1254. strPlayerList += csprintf("\nEnd of Player List (%lu)", (DWORD)pPlayers->size());
  1255. pPlayer->SendText(strPlayerList.c_str(), 1);
  1256. }
  1257. else
  1258. return true;
  1259. return false;
  1260. }
  1261. CLIENT_COMMAND(tabletest, "", "Performs a table test.", BASIC_ACCESS)
  1262. {
  1263. if (argc < 1)
  1264. return true;
  1265. long value = atol(argv[0]);
  1266. pPlayer->SendText(csprintf("Level: %lu", GetAttributeXP(value)), 1);
  1267. return false;
  1268. }
  1269. CLIENT_COMMAND(doomshard, "[palette=0xBF7]", "Spawns a doom shard.", BASIC_ACCESS)
  1270. {
  1271. if (!SpawningEnabled(pPlayer))
  1272. {
  1273. return false;
  1274. }
  1275. WORD palette = 0xBF7;
  1276. if (argc >= 1)
  1277. palette = (unsigned short)strtoul(argv[0], NULL, 16);
  1278. CBaseMonster *pDoomShard = new CBaseMonster();
  1279. pDoomShard->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  1280. pDoomShard->m_dwModel = 0x02000700;
  1281. pDoomShard->m_fScale = 1.6f;
  1282. pDoomShard->m_strName = "Doom Shard";
  1283. pDoomShard->m_Origin = pPlayer->m_Origin;
  1284. pDoomShard->m_miBaseModel.dwBasePalette = 0xBEF;
  1285. pDoomShard->m_miBaseModel.lPalettes.push_back(PaletteRpl(palette, 0x00, 0x00));
  1286. g_pWorld->CreateEntity(pDoomShard);
  1287. return false;
  1288. }
  1289. CLIENT_COMMAND(spawnaerfalle, "", "Spawn aerfalle for testing if the data is available.", ADMIN_ACCESS)
  1290. {
  1291. if (!SpawningEnabled(pPlayer))
  1292. {
  1293. return false;
  1294. }
  1295. g_pGameDatabase->SpawnAerfalle();
  1296. return false;
  1297. }
  1298. CLIENT_COMMAND(freecam, "", "Allows free camera movement.", BASIC_ACCESS)
  1299. {
  1300. pPlayer->ChangeVIS(pPlayer->m_PhysicsState ^ (DWORD)(PARTICLE_EMITTER_PS));
  1301. return false;
  1302. }
  1303. CLIENT_COMMAND(spawn, "[name] [scale] [animate 0=no 1=yes]", "Spawns something by name (right now works for monsters, NPCs, players.)", BASIC_ACCESS)
  1304. {
  1305. if (!SpawningEnabled(pPlayer))
  1306. {
  1307. return false;
  1308. }
  1309. if (argc < 1)
  1310. return true;
  1311. CCapturedWorldObjectInfo *pMonsterInfo = g_pGameDatabase->GetCapturedMonsterData(argv[0]);
  1312. if (!pMonsterInfo)
  1313. {
  1314. pPlayer->SendText("Couldn't find that to spawn!", 1);
  1315. return false;
  1316. }
  1317. float fScale = 1.0f;
  1318. if (argc >= 2)
  1319. {
  1320. fScale = (float) atof(argv[1]);
  1321. if (fScale < 0.01)
  1322. fScale = 0.01f;
  1323. if (fScale > 1000.0)
  1324. fScale = 1000;
  1325. }
  1326. bool bAnimate = true;
  1327. if (argc >= 3)
  1328. {
  1329. bAnimate = atoi(argv[2]) ? true : false;
  1330. }
  1331. CPhysicsObj *pMonster = g_pGameDatabase->CreateFromCapturedData(pMonsterInfo);
  1332. // Modify these
  1333. pMonster->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  1334. pMonster->m_fScale = pMonsterInfo->physics.object_scale * fScale;
  1335. pMonster->m_Origin = pPlayer->m_Origin;
  1336. // Add and spawn it
  1337. g_pWorld->CreateEntity(pMonster);
  1338. pMonster->PostSpawn();
  1339. return false;
  1340. }
  1341. CLIENT_COMMAND(spawnitem2, "[name] [scale", "Spawns something by name (works for most items.)", BASIC_ACCESS)
  1342. {
  1343. if (!SpawningEnabled(pPlayer))
  1344. {
  1345. return false;
  1346. }
  1347. if (argc < 1)
  1348. {
  1349. return true;
  1350. }
  1351. CCapturedWorldObjectInfo *pItemInfo = g_pGameDatabase->GetCapturedItemData(argv[0]);
  1352. if (!pItemInfo)
  1353. {
  1354. pPlayer->SendText("Couldn't find that to spawn!", 1);
  1355. return false;
  1356. }
  1357. float fScale = 1.0f;
  1358. if (argc >= 2)
  1359. {
  1360. fScale = (float)atof(argv[1]);
  1361. if (fScale < 0.01)
  1362. fScale = 0.01f;
  1363. if (fScale > 1000.0)
  1364. fScale = 1000;
  1365. }
  1366. CPhysicsObj *pItem = g_pGameDatabase->CreateFromCapturedData(pItemInfo);
  1367. pItem->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  1368. pItem->m_fScale = pItemInfo->physics.object_scale * fScale;
  1369. pItem->m_Origin = pPlayer->m_Origin;
  1370. pItem->m_dwCoverage2 = 0; // Not equipped
  1371. g_pWorld->CreateEntity(pItem);
  1372. return false;
  1373. }
  1374. CLIENT_COMMAND(spawnarmor, "[name]", "Spawns armor by name.", BASIC_ACCESS)
  1375. {
  1376. if (!SpawningEnabled(pPlayer))
  1377. {
  1378. return false;
  1379. }
  1380. if (argc < 1)
  1381. {
  1382. return true;
  1383. }
  1384. CCapturedWorldObjectInfo *pItemInfo = g_pGameDatabase->GetCapturedArmorData(argv[0]);
  1385. if (!pItemInfo)
  1386. {
  1387. pPlayer->SendText("Couldn't find that to spawn!", 1);
  1388. return false;
  1389. }
  1390. float fScale = 1.0f;
  1391. bool bAnimate = true;
  1392. if (argc >= 2)
  1393. {
  1394. fScale = (float)atof(argv[1]);
  1395. if (fScale < 0.01)
  1396. fScale = 0.01f;
  1397. if (fScale > 1000.0)
  1398. fScale = 1000;
  1399. }
  1400. if (argc >= 3)
  1401. {
  1402. bAnimate = atoi(argv[2]) ? true : false;
  1403. }
  1404. CPhysicsObj *pItem = g_pGameDatabase->CreateFromCapturedData(pItemInfo);
  1405. pItem->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  1406. pItem->m_fScale = pItemInfo->physics.object_scale * fScale;
  1407. pItem->m_dwCoverage2 = 0;
  1408. pItem->m_Origin = pPlayer->m_Origin;
  1409. if (!bAnimate)
  1410. {
  1411. pItem->m_AnimOverrideData = NULL;
  1412. pItem->m_AnimOverrideDataLen = 0;
  1413. pItem->m_AutonomousMovement = 0;
  1414. }
  1415. g_pWorld->CreateEntity(pItem);
  1416. return false;
  1417. }
  1418. CLIENT_COMMAND(spawnlist, "[num to list]", "Lists spawnable objects.", BASIC_ACCESS)
  1419. {
  1420. int num = 20;
  1421. if (argc >= 1)
  1422. {
  1423. num = atoi(argv[0]);
  1424. if (num < 0)
  1425. num = 0;
  1426. if (num >= 100)
  1427. num = 100;
  1428. }
  1429. while (num > 0)
  1430. {
  1431. CCapturedWorldObjectInfo *pMonsterInfo = g_pGameDatabase->GetRandomCapturedMonsterData();
  1432. if (!pMonsterInfo)
  1433. {
  1434. pPlayer->SendText("Couldn't find anything to spawn!", 1);
  1435. return false;
  1436. }
  1437. pPlayer->SendText(pMonsterInfo->weenie._name.c_str(), 1);
  1438. num--;
  1439. }
  1440. return false;
  1441. }
  1442. CLIENT_COMMAND(spawnrandomarmor, "", "Spawns random armor.", BASIC_ACCESS)
  1443. {
  1444. if (!SpawningEnabled(pPlayer))
  1445. {
  1446. return false;
  1447. }
  1448. CCapturedWorldObjectInfo *pItemInfo = g_pGameDatabase->GetRandomCapturedArmorData();
  1449. if (!pItemInfo)
  1450. {
  1451. pPlayer->SendText("Couldn't find anything to spawn!", 1);
  1452. return false;
  1453. }
  1454. CPhysicsObj *pItem = g_pGameDatabase->CreateFromCapturedData(pItemInfo);
  1455. pItem->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  1456. pItem->m_dwCoverage2 = 0;
  1457. pItem->m_Origin = pPlayer->m_Origin;
  1458. pItem->m_dwEquipSlot = 0; // ???
  1459. pItem->m_dwEquipType = 0; // ???
  1460. pItem->m_AnimOverrideData = NULL;
  1461. pItem->m_AnimOverrideDataLen = 0;
  1462. pItem->m_AutonomousMovement = 0;
  1463. g_pWorld->CreateEntity(pItem);
  1464. return false;
  1465. }
  1466. CLIENT_COMMAND(spawnrandom, "[num to spawn] [scale]", "Spawns random objects.", BASIC_ACCESS)
  1467. {
  1468. if (argc < 1)
  1469. {
  1470. return true;
  1471. }
  1472. if (!SpawningEnabled(pPlayer))
  1473. {
  1474. return false;
  1475. }
  1476. int num = atoi(argv[0]);
  1477. if (num < 0)
  1478. num = 0;
  1479. if (num >= 20)
  1480. num = 20;
  1481. float fScale = 1.0f;
  1482. if (argc >= 2)
  1483. {
  1484. fScale = (float) atof(argv[1]);
  1485. if (fScale < 0.01f)
  1486. fScale = 0.01f;
  1487. if (fScale >= 1000.0f)
  1488. fScale = 1000.0f;
  1489. }
  1490. int total = num;
  1491. while (num > 0)
  1492. {
  1493. CCapturedWorldObjectInfo *pMonsterInfo = g_pGameDatabase->GetRandomCapturedMonsterData();
  1494. if (!pMonsterInfo)
  1495. {
  1496. pPlayer->SendText("Couldn't find anything to spawn!", 1);
  1497. return false;
  1498. }
  1499. CPhysicsObj *pMonster = g_pGameDatabase->CreateFromCapturedData(pMonsterInfo);
  1500. pMonster->m_dwGUID = g_pWorld->GenerateGUID(eDynamicGUID);
  1501. pMonster->m_fScale = pMonsterInfo->physics.object_scale * fScale;
  1502. pMonster->m_dwCoverage2 = 0;
  1503. pMonster->m_AnimOverrideData = NULL;
  1504. pMonster->m_AnimOverrideDataLen = 0;
  1505. pMonster->m_AutonomousMovement = 0;
  1506. pMonster->m_Origin = pPlayer->m_Origin;
  1507. pMonster->m_Origin.x += (float)RandomFloat(-2.0f * total, 2.0f * total);
  1508. pMonster->m_Origin.y += (float)RandomFloat(-2.0f * total, 2.0f * total);
  1509. g_pWorld->CreateEntity(pMonster);
  1510. pMonster->PostSpawn();
  1511. num--;
  1512. }
  1513. return false;
  1514. }
  1515. const char* CommandBase::Info(CommandEntry* pCommand)
  1516. {
  1517. const char* szName = pCommand->name;
  1518. const char* szArgs = pCommand->args;
  1519. const char* szHelp = pCommand->help;
  1520. if (strlen(szArgs) <= 0)
  1521. return csprintf("Syntax: @%s - %s", szName, szHelp);
  1522. else
  1523. return csprintf("Syntax: @%s %s - %s", szName, szArgs, szHelp);
  1524. }
  1525. CommandEntry* CommandBase::FindCommand(const char* szName, int iAccessLevel)
  1526. {
  1527. CommandMap::iterator i = m_mCommands.find(szName);
  1528. if (i == m_mCommands.end())
  1529. return NULL;
  1530. if (iAccessLevel == -1 || iAccessLevel >= i->second.access)
  1531. return &i->second;
  1532. else
  1533. return NULL;
  1534. }
  1535. bool CommandBase::Execute(char* szCommand, CBasePlayer *pPlayer, int iAccessLevel)
  1536. {
  1537. char* argv[MAX_ARGUMENTS];
  1538. int argc = 0;
  1539. bool inquote = false;
  1540. char *argstart = szCommand;
  1541. char *p = szCommand;
  1542. // Quote-delimited arguments.
  1543. for (; p[0] != '\0' && argc < MAX_ARGUMENTS; p++)
  1544. {
  1545. char feed = p[0];
  1546. if (inquote)
  1547. {
  1548. if (feed == '\"')
  1549. {
  1550. inquote = false;
  1551. *p = 0;
  1552. argv[argc++] = argstart;
  1553. argstart = p + 1;
  1554. continue;
  1555. }
  1556. }
  1557. else
  1558. {
  1559. if (feed == ' ')
  1560. {
  1561. if (argstart == p)
  1562. argstart++;
  1563. else
  1564. {
  1565. *p = 0;
  1566. argv[argc++] = argstart;
  1567. argstart = p + 1;
  1568. }
  1569. }
  1570. if (feed == '\"')
  1571. {
  1572. inquote = true;
  1573. argstart = p + 1;
  1574. }
  1575. }
  1576. }
  1577. if (argstart[0] != 0 && argc < MAX_ARGUMENTS)
  1578. {
  1579. argv[argc++] = argstart;
  1580. }
  1581. if (argc > 0)
  1582. {
  1583. char* szCommandName = argv[0];
  1584. if (!stricmp(szCommandName, "help"))
  1585. {
  1586. if (!pPlayer)
  1587. return true;
  1588. if (argc > 1) {
  1589. CommandEntry* pCommand = FindCommand(argv[1], iAccessLevel);
  1590. if (pCommand)
  1591. {
  1592. pPlayer->SendText(Info(pCommand), 1);
  1593. return true;
  1594. }
  1595. else
  1596. pPlayer->SendText("Unknown command. Use !help to receive a list of commands.", 1);
  1597. }
  1598. else
  1599. {
  1600. // List all commands.
  1601. std::string strCommandList = "Command List: \n";
  1602. for (CommandMap::iterator it = m_mCommands.begin(); it != m_mCommands.end(); it++)
  1603. {
  1604. if (it->second.access <= iAccessLevel) {
  1605. strCommandList += Info(&it->second);
  1606. strCommandList += "\n";
  1607. }
  1608. }
  1609. strCommandList += "Use !help <command> to receive command syntax.\n";
  1610. pPlayer->SendText(strCommandList.c_str(), 1);
  1611. return true;
  1612. }
  1613. }
  1614. else
  1615. {
  1616. CommandEntry* pCommand = FindCommand(szCommandName, iAccessLevel);
  1617. if (!pCommand)
  1618. {
  1619. if (pPlayer)
  1620. pPlayer->SendText("Unknown command!", 1);
  1621. }
  1622. else
  1623. {
  1624. if (!pCommand->source || pPlayer)
  1625. {
  1626. // Run the command callback.
  1627. if ((*pCommand->func)(pPlayer, argv + 1, argc - 1))
  1628. {
  1629. //Error
  1630. if (pPlayer)
  1631. pPlayer->SendText(Info(pCommand), 1);
  1632. }
  1633. else
  1634. return true;
  1635. }
  1636. }
  1637. }
  1638. }
  1639. return false;
  1640. }
  1641. ClientCommand::ClientCommand(const char* szName, const char* szArguments, const char* szHelp, pfnCommandCallback pCallback, int iAccessLevel)
  1642. {
  1643. CommandBase::Create(szName, szArguments, szHelp, pCallback, iAccessLevel, true);
  1644. }
  1645. ServerCommand::ServerCommand(const char* szName, const char* szArguments, const char* szHelp, pfnCommandCallback pCallback, int iAccessLevel)
  1646. {
  1647. CommandBase::Create(szName, szArguments, szHelp, pCallback, iAccessLevel, false);
  1648. }