Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Command.cpp 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. /*!
  2. * \file src/Command.cpp
  3. * \brief OpenRaider command implementation
  4. *
  5. * \author xythobuz
  6. */
  7. #include <fstream>
  8. #include <sstream>
  9. #include "global.h"
  10. #include "Camera.h"
  11. #include "Console.h"
  12. #include "Entity.h"
  13. #include "Font.h"
  14. #include "Game.h"
  15. #include "math/math.h"
  16. #include "Menu.h"
  17. #include "Render.h"
  18. #include "Sound.h"
  19. #include "TombRaider.h"
  20. #include "Window.h"
  21. #include "World.h"
  22. #include "utils/strings.h"
  23. #include "utils/time.h"
  24. #include "OpenRaider.h"
  25. int OpenRaider::loadConfig(const char *config) {
  26. assert(config != NULL);
  27. assert(config[0] != '\0');
  28. char *configFile = fullPath(config, 0);
  29. getConsole().print("Loading config from \"%s\"...", configFile);
  30. std::ifstream file(configFile);
  31. if (!file) {
  32. getConsole().print("Could not open file!");
  33. return -1;
  34. }
  35. for (std::string line; std::getline(file, line);) {
  36. if (line.length() == 0)
  37. continue;
  38. int error = command(line);
  39. if (error != 0)
  40. getConsole().print("Error Code: %d", error);
  41. }
  42. file.close();
  43. return 0;
  44. }
  45. int OpenRaider::command(const char *command) {
  46. std::string tmp(command);
  47. return this->command(tmp);
  48. }
  49. int OpenRaider::command(std::string &c) {
  50. // Remove comment, if any
  51. size_t comment = c.find_first_of('#');
  52. if (comment != std::string::npos)
  53. c.erase(comment);
  54. // Execute command
  55. std::stringstream command(c);
  56. std::string cmd;
  57. command >> cmd;
  58. command >> std::boolalpha >> std::ws;
  59. if (cmd.length() == 0)
  60. return 0;
  61. if (cmd.compare("set") == 0) {
  62. return set(command);
  63. } else if (cmd.compare("bind") == 0) {
  64. std::string a, b;
  65. if (!(command >> a >> b)) {
  66. getConsole().print("Invalid use of bind-command");
  67. return -1;
  68. } else {
  69. return bind(a.c_str(), b.c_str());
  70. }
  71. } else if (cmd.compare("quit") == 0) {
  72. exit(0);
  73. } else if (cmd.compare("load") == 0) {
  74. if (!mRunning) {
  75. getConsole().print("Use load command interactively!");
  76. return -999;
  77. }
  78. std::string temp;
  79. command >> temp;
  80. char *tmp = bufferString("%s/%s", mPakDir, temp.c_str());
  81. int error = getGame().loadLevel(tmp);
  82. delete [] tmp;
  83. return error;
  84. } else if (cmd.compare("help") == 0) {
  85. std::string tmp;
  86. if (!(command >> tmp)) {
  87. getConsole().print("Available commands:");
  88. getConsole().print(" load - load a level");
  89. getConsole().print(" set - set a parameter");
  90. getConsole().print(" bind - bind a keyboard/mouse action");
  91. getConsole().print(" animate - [BOOL|n|p] - Animate models");
  92. getConsole().print(" move - [walk|fly|noclip]");
  93. /*
  94. getConsole().print(" sshot - make a screenshot");
  95. getConsole().print(" sound - INT - Test play sound");
  96. getConsole().print(" mode - MODE - Render mode");
  97. getConsole().print(" light - BOOL - GL Lights");
  98. getConsole().print(" fog - BOOL - GL Fog");
  99. getConsole().print(" viewmodel - INT - Change Laras model");
  100. getConsole().print(" pos - Print position info");
  101. getConsole().print(" ralpha - BOOL - Room Alpha");
  102. getConsole().print(" upf - BOOL - Update Room List Per Frame");
  103. getConsole().print(" entmodel - BOOL");
  104. getConsole().print(" ponytail - BOOL");
  105. getConsole().print(" pigtail - BOOL");
  106. getConsole().print(" ponypos - FLOAT FLOAT FLOAT FLOAT - x y z angle");
  107. */
  108. getConsole().print(" help - print command help");
  109. getConsole().print(" quit - exit OpenRaider");
  110. getConsole().print("Use help COMMAND to get additional info");
  111. getConsole().print("Pass BOOLs as true or false");
  112. } else {
  113. return help(tmp);
  114. }
  115. } else if (cmd.compare("animate") == 0) {
  116. if ((!mRunning) || (!getGame().isLoaded())) {
  117. getConsole().print("Use animate command interactively!");
  118. return -999;
  119. }
  120. if (command.peek() == 'n') {
  121. // Step all skeletal models to their next animation
  122. if (getRender().getFlags() & Render::fAnimateAllModels) {
  123. for (unsigned int i = 0; i < getWorld().sizeEntity(); i++) {
  124. Entity &e = getWorld().getEntity(i);
  125. SkeletalModel &m = e.getModel();
  126. if (e.getAnimation() < (m.size() - 1))
  127. e.setAnimation(e.getAnimation() + 1);
  128. else
  129. e.setAnimation(0);
  130. }
  131. } else {
  132. getConsole().print("Animations need to be enabled!");
  133. }
  134. } else if (command.peek() == 'p') {
  135. // Step all skeletal models to their previous animation
  136. if (getRender().getFlags() & Render::fAnimateAllModels) {
  137. for (unsigned int i = 0; i < getWorld().sizeEntity(); i++) {
  138. Entity &e = getWorld().getEntity(i);
  139. SkeletalModel &m = e.getModel();
  140. if (e.getAnimation() > 0)
  141. e.setAnimation(e.getAnimation() - 1);
  142. else
  143. if (m.size() > 0)
  144. e.setAnimation(m.size() - 1);
  145. }
  146. } else {
  147. getConsole().print("Animations need to be enabled!");
  148. }
  149. } else {
  150. // Enable or disable animating all skeletal models
  151. bool b = false;
  152. if (!(command >> b)) {
  153. getConsole().print("Pass BOOL to animate command!");
  154. return -2;
  155. }
  156. if (b)
  157. getRender().setFlags(Render::fAnimateAllModels);
  158. else
  159. getRender().clearFlags(Render::fAnimateAllModels);
  160. getConsole().print(b ? "Animating all models" : "No longer animating all models");
  161. }
  162. } else if (cmd.compare("move") == 0) {
  163. if ((!mRunning) || (!getGame().isLoaded())) {
  164. getConsole().print("Use move command interactively!");
  165. return -999;
  166. }
  167. std::string temp;
  168. command >> temp;
  169. if (temp.compare("walk") == 0) {
  170. getGame().getLara().setMoveType(Entity::MoveTypeWalk);
  171. } else if (temp.compare("fly") == 0) {
  172. getGame().getLara().setMoveType(Entity::MoveTypeFly);
  173. } else if (temp.compare("noclip") == 0) {
  174. getGame().getLara().setMoveType(Entity::MoveTypeNoClipping);
  175. } else {
  176. getConsole().print("Invalid use of move command (%s)!", temp.c_str());
  177. return -9;
  178. }
  179. getConsole().print("%sing", temp.c_str());
  180. /*
  181. } else if (cmd.compare("mode") == 0) {
  182. std::string mode;
  183. command >> mode;
  184. if (!getGame().isLoaded()) {
  185. getConsole().print("Load a level to set the mode!");
  186. return -1;
  187. }
  188. if (mode.compare("wireframe") == 0) {
  189. getRender().setMode(Render::modeWireframe);
  190. getConsole().print("Wireframe mode");
  191. } else if (mode.compare("solid") == 0) {
  192. getRender().setMode(Render::modeSolid);
  193. getConsole().print("Solid mode");
  194. } else if (mode.compare("texture") == 0) {
  195. getRender().setMode(Render::modeTexture);
  196. getConsole().print("Texture mode");
  197. } else if (mode.compare("vertexlight") == 0) {
  198. getRender().setMode(Render::modeVertexLight);
  199. getConsole().print("Vertexlight mode");
  200. } else if (mode.compare("titlescreen") == 0) {
  201. getRender().setMode(Render::modeLoadScreen);
  202. getConsole().print("Titlescreen mode");
  203. } else {
  204. getConsole().print("Invalid use of mode command (%s)!", mode.c_str());
  205. return -1;
  206. }
  207. } else if (cmd.compare("light") == 0) {
  208. if (args->size() > 0) {
  209. bool b;
  210. if (readBool(args->at(0), &b) < 0) {
  211. getConsole().print("Pass BOOL to light command!");
  212. return -15;
  213. }
  214. if (b)
  215. getRender().setFlags(Render::fGL_Lights);
  216. else
  217. getRender().clearFlags(Render::fGL_Lights);
  218. getConsole().print("GL-Lights are now %s", b ? "on" : "off");
  219. } else {
  220. getConsole().print("Invalid use of light-command!");
  221. return -16;
  222. }
  223. } else if (cmd.compare("fog") == 0) {
  224. if (args->size() > 0) {
  225. bool b;
  226. if (readBool(args->at(0), &b) < 0) {
  227. getConsole().print("Pass BOOL to fog command!");
  228. return -17;
  229. }
  230. if (b)
  231. getRender().setFlags(Render::fFog);
  232. else
  233. getRender().clearFlags(Render::fFog);
  234. getConsole().print("Fog is now %s", b ? "on" : "off");
  235. } else {
  236. getConsole().print("Invalid use of fog-command!");
  237. return -18;
  238. }
  239. } else if (cmd.compare("ralpha") == 0) {
  240. if (args->size() > 0) {
  241. bool b;
  242. if (readBool(args->at(0), &b) < 0) {
  243. getConsole().print("Pass BOOL to ralpha command!");
  244. return -24;
  245. }
  246. if (b)
  247. getRender().setFlags(Render::fRoomAlpha);
  248. else
  249. getRender().clearFlags(Render::fRoomAlpha);
  250. getConsole().print("Room Alpha is now %s", b ? "on" : "off");
  251. } else {
  252. getConsole().print("Invalid use of ralpha-command!");
  253. return -25;
  254. }
  255. } else if (cmd.compare("upf") == 0) {
  256. if (args->size() > 0) {
  257. bool b;
  258. if (readBool(args->at(0), &b) < 0) {
  259. getConsole().print("Pass BOOL to upf command!");
  260. return -30;
  261. }
  262. if (b)
  263. getRender().setFlags(Render::fUpdateRoomListPerFrame);
  264. else
  265. getRender().clearFlags(Render::fUpdateRoomListPerFrame);
  266. getConsole().print("URLPF is now %s", b ? "on" : "off");
  267. } else {
  268. getConsole().print("Invalid use of upf-command!");
  269. return -31;
  270. }
  271. } else if (cmd.compare("entmodel") == 0) {
  272. if (args->size() > 0) {
  273. bool b;
  274. if (readBool(args->at(0), &b) < 0) {
  275. getConsole().print("Pass BOOL to entmodel command!");
  276. return -38;
  277. }
  278. if (b)
  279. getRender().setFlags(Render::fEntityModels);
  280. else
  281. getRender().clearFlags(Render::fEntityModels);
  282. getConsole().print("Entmodels are now %s", b ? "on" : "off");
  283. } else {
  284. getConsole().print("Invalid use of entmodel-command!");
  285. return -39;
  286. }
  287. } else if (cmd.compare("ponytail") == 0) {
  288. if (args->size() > 0) {
  289. bool b;
  290. if (readBool(args->at(0), &b) < 0) {
  291. getConsole().print("Pass BOOL to ponytail command!");
  292. return -44;
  293. }
  294. if (b)
  295. getRender().setFlags(Render::fRenderPonytail);
  296. else
  297. getRender().clearFlags(Render::fRenderPonytail);
  298. getConsole().print("Ponytail is now %s", b ? "on" : "off");
  299. } else {
  300. getConsole().print("Invalid use of ponytail-command!");
  301. return -45;
  302. }
  303. } else if (cmd.compare("sshot") == 0) {
  304. if (!mRunning) {
  305. getConsole().print("Use sshot command interactively!");
  306. return -999;
  307. }
  308. char *filename = bufferString("%s/sshots/%s", mBaseDir, VERSION);
  309. bool console = (args->size() > 0) && (strcmp(args->at(0), "console") == 0);
  310. bool menu = (args->size() > 0) && (strcmp(args->at(0), "menu") == 0);
  311. if (!console) {
  312. getConsole().setVisible(false);
  313. if (menu)
  314. getMenu().setVisible(true);
  315. frame();
  316. frame(); // Double buffered
  317. }
  318. getRender().screenShot(filename);
  319. if (!console) {
  320. getConsole().setVisible(true);
  321. if (menu)
  322. getMenu().setVisible(false);
  323. }
  324. getConsole().print("Screenshot stored...");
  325. delete filename;
  326. } else if (cmd.compare("sound") == 0) {
  327. if ((!mRunning) || (!getGame().isLoaded())) {
  328. getConsole().print("Use sound command interactively!");
  329. return -999;
  330. }
  331. if (args->size() > 0) {
  332. getSound().play(atoi(args->at(0)));
  333. } else {
  334. getConsole().print("Invalid use of sound command!");
  335. return -12;
  336. }
  337. } else if (cmd.compare("viewmodel") == 0) {
  338. if ((!mRunning) || (!getGame().isLoaded())) {
  339. getConsole().print("Use viewmodel command interactively!");
  340. return -999;
  341. }
  342. unsigned int n = atoi(args->at(0));
  343. if (n < getWorld().sizeSkeletalModel())
  344. getGame().getLara().setSkeletalModel(n);
  345. else {
  346. getConsole().print("Invalid SkeletalModel index!");
  347. return -66;
  348. }
  349. } else if (cmd.compare("pos") == 0) {
  350. if ((!mRunning) || (!getGame().isLoaded())) {
  351. getConsole().print("Use pos command interactively!");
  352. return -21;
  353. }
  354. getGame().getLara().print();
  355. } else if (cmd.compare("pigtail") == 0) {
  356. if ((!mRunning) || (!getGame().isLoaded())) {
  357. getConsole().print("Use pigtail command interactively!");
  358. return -999;
  359. }
  360. if (args->size() > 0) {
  361. bool b;
  362. if (readBool(args->at(0), &b) < 0) {
  363. getConsole().print("Pass BOOL to pigtail command!");
  364. return -46;
  365. }
  366. SkeletalModel &tmp = getGame().getLara().getModel();
  367. tmp.setPigTail(b);
  368. getConsole().print("Pigtail is now %s", b ? "on" : "off");
  369. } else {
  370. getConsole().print("Invalid use of pigtail-command!");
  371. return -47;
  372. }
  373. } else if (cmd.compare("ponypos") == 0) {
  374. if ((!mRunning) || (!getGame().isLoaded())) {
  375. getConsole().print("Use ponypos command interactively!");
  376. return -999;
  377. }
  378. if (args->size() > 3) {
  379. SkeletalModel &tmp = getGame().getLara().getModel();
  380. tmp.setPonyPos((float)atof(args->at(0)), (float)atof(args->at(1)),
  381. (float)atof(args->at(2)), (float)atof(args->at(3)));
  382. } else {
  383. getConsole().print("Invalid use of ponypos-command!");
  384. return -48;
  385. }
  386. */
  387. } else {
  388. getConsole().print("Unknown command: %s", cmd.c_str());
  389. return -50;
  390. }
  391. return 0;
  392. }
  393. int OpenRaider::help(std::string &cmd) {
  394. if (cmd.compare("set") == 0) {
  395. getConsole().print("set-Command Usage:");
  396. getConsole().print(" set VAR VAL");
  397. getConsole().print("Available Variables:");
  398. getConsole().print(" basedir STRING");
  399. getConsole().print(" pakdir STRING");
  400. getConsole().print(" audiodir STRING");
  401. getConsole().print(" datadir STRING");
  402. getConsole().print(" font STRING");
  403. getConsole().print(" size INT INT");
  404. getConsole().print(" fullscreen BOOL");
  405. getConsole().print(" audio BOOL");
  406. getConsole().print(" volume BOOL");
  407. getConsole().print(" mouse_x FLOAT");
  408. getConsole().print(" mouse_y FLOAT");
  409. getConsole().print(" fps BOOL");
  410. getConsole().print("Enclose STRINGs with \"\"!");
  411. } else if (cmd.compare("bind") == 0) {
  412. getConsole().print("bind-Command Usage:");
  413. getConsole().print(" bind ACTION KEY");
  414. getConsole().print("Available Actions:");
  415. getConsole().print(" menu");
  416. getConsole().print(" console");
  417. getConsole().print(" forward");
  418. getConsole().print(" backward");
  419. getConsole().print(" left");
  420. getConsole().print(" right");
  421. getConsole().print(" jump");
  422. getConsole().print(" crouch");
  423. getConsole().print(" use");
  424. getConsole().print(" holster");
  425. getConsole().print(" walk");
  426. getConsole().print("Key-Format:");
  427. getConsole().print(" 'a' or '1' for character/number keys");
  428. getConsole().print(" \"leftctrl\" for symbols and special keys");
  429. } else if (cmd.compare("load") == 0) {
  430. getConsole().print("load-Command Usage:");
  431. getConsole().print(" load levelfile.name");
  432. /*
  433. } else if (cmd.compare("sshot") == 0) {
  434. getConsole().print("sshot-Command Usage:");
  435. getConsole().print(" sshot [console|menu]");
  436. getConsole().print("Add console/menu to capture them too");
  437. } else if (cmd.compare("sound") == 0) {
  438. getConsole().print("sound-Command Usage:");
  439. getConsole().print(" sound INT");
  440. getConsole().print("Where INT is a valid sound ID integer");
  441. } else if (cmd.compare("move") == 0) {
  442. getConsole().print("move-Command Usage:");
  443. getConsole().print(" move COMMAND");
  444. getConsole().print("Where COMMAND is one of the following:");
  445. getConsole().print(" walk");
  446. getConsole().print(" fly");
  447. getConsole().print(" noclip");
  448. } else if (cmd.compare("mode") == 0) {
  449. getConsole().print("mode-Command Usage:");
  450. getConsole().print(" mode MODE");
  451. getConsole().print("Where MODE is one of the following:");
  452. getConsole().print(" wireframe");
  453. getConsole().print(" solid");
  454. getConsole().print(" texture");
  455. getConsole().print(" vertexlight");
  456. getConsole().print(" titlescreen");
  457. */
  458. } else if (cmd.compare("animate") == 0) {
  459. getConsole().print("animate-Command Usage:");
  460. getConsole().print(" animate [n|p|BOOL]");
  461. getConsole().print("Where the commands have the following meaning:");
  462. getConsole().print(" BOOL to (de)activate animating all models");
  463. getConsole().print(" n to step all models to their next animation");
  464. getConsole().print(" p to step all models to their previous animation");
  465. } else {
  466. getConsole().print("No help available for %s", cmd.c_str());
  467. return -1;
  468. }
  469. return 0;
  470. }
  471. char *OpenRaider::expandDirectoryNames(const char *s) {
  472. assert(s != NULL);
  473. assert(s[0] != '\0');
  474. char *result = bufferString("%s", s);
  475. if (mPakDir != NULL) {
  476. char *tmp = stringReplace(s, "$(pakdir)", mPakDir);
  477. delete [] result;
  478. result = tmp;
  479. }
  480. if (mAudioDir != NULL) {
  481. char *tmp = stringReplace(s, "$(audiodir)", mAudioDir);
  482. delete [] result;
  483. result = tmp;
  484. }
  485. if (mDataDir != NULL) {
  486. char *tmp = stringReplace(s, "$(datadir)", mDataDir);
  487. delete [] result;
  488. result = tmp;
  489. }
  490. if (mBaseDir != NULL) {
  491. char *tmp = stringReplace(result, "$(basedir)", mBaseDir);
  492. delete [] result;
  493. result = tmp;
  494. }
  495. return result;
  496. }
  497. #define CHANGE_DIR_WITH_EXPANSION(a) do { \
  498. std::string temp; \
  499. command >> temp; \
  500. const char *value = temp.c_str(); \
  501. char *quotes = stringRemoveQuotes(value); \
  502. char *tmp = expandDirectoryNames(quotes); \
  503. a = fullPath(tmp, 0); \
  504. delete [] tmp; \
  505. delete [] quotes; \
  506. } while(false)
  507. int OpenRaider::set(std::istream &command) {
  508. std::string var;
  509. command >> var;
  510. if (var.compare("size") == 0) {
  511. unsigned int w = DEFAULT_WIDTH, h = DEFAULT_HEIGHT;
  512. if (!(command >> w >> h)) {
  513. getConsole().print("set-size-Error: Invalid value(s)");
  514. return -2;
  515. }
  516. getWindow().setSize(w, h);
  517. } else if (var.compare("fullscreen") == 0) {
  518. bool fullscreen = false;
  519. if (!(command >> fullscreen)) {
  520. getConsole().print("set-fullscreen-Error: Invalid value");
  521. return -3;
  522. }
  523. getWindow().setFullscreen(fullscreen);
  524. } else if (var.compare("audio") == 0) {
  525. bool audio = false;
  526. if (!(command >> audio)) {
  527. getConsole().print("set-audio-Error: Invalid value");
  528. return -4;
  529. }
  530. getSound().setEnabled(audio);
  531. } else if (var.compare("volume") == 0) {
  532. float vol = 1.0f;
  533. if (!(command >> vol)) {
  534. getConsole().print("set-volume-Error: Invalid value");
  535. return -5;
  536. }
  537. getSound().setVolume(vol);
  538. } else if (var.compare("mouse_x") == 0) {
  539. float sense = 1.0f;
  540. if (!(command >> sense)) {
  541. getConsole().print("set-mouse_x-Error: Invalid value");
  542. return -6;
  543. }
  544. getCamera().setSensitivityX(OR_DEG_TO_RAD(sense));
  545. } else if (var.compare("mouse_y") == 0) {
  546. float sense = 1.0f;
  547. if (!(command >> sense)) {
  548. getConsole().print("set-mouse_y-Error: Invalid value");
  549. return -7;
  550. }
  551. getCamera().setSensitivityY(OR_DEG_TO_RAD(sense));
  552. } else if (var.compare("fps") == 0) {
  553. bool fps = false;
  554. if (!(command >> fps)) {
  555. getConsole().print("set-fps-Error: Invalid value");
  556. return -8;
  557. }
  558. mFPS = fps;
  559. } else if (var.compare("basedir") == 0) {
  560. CHANGE_DIR_WITH_EXPANSION(mBaseDir);
  561. } else if (var.compare("pakdir") == 0) {
  562. CHANGE_DIR_WITH_EXPANSION(mPakDir);
  563. } else if (var.compare("audiodir") == 0) {
  564. CHANGE_DIR_WITH_EXPANSION(mAudioDir);
  565. } else if (var.compare("datadir") == 0) {
  566. CHANGE_DIR_WITH_EXPANSION(mDataDir);
  567. } else if (var.compare("font") == 0) {
  568. std::string temp;
  569. command >> temp;
  570. const char *value = temp.c_str();
  571. char *quotes = stringReplace(value, "\"", "");
  572. char *tmp = expandDirectoryNames(quotes);
  573. getFont().setFont(tmp);
  574. delete [] tmp;
  575. delete [] quotes;
  576. } else {
  577. getConsole().print("set-Error: Unknown variable (%s)", var.c_str());
  578. return -1;
  579. }
  580. return 0;
  581. }
  582. int OpenRaider::bind(const char *action, const char *key) {
  583. assert(action != NULL);
  584. assert(action[0] != '\0');
  585. assert(key != NULL);
  586. assert(key[0] != '\0');
  587. ActionEvents e = stringToActionEvent(action);
  588. if (e == ActionEventCount) {
  589. getConsole().print("bind-Error: Unknown action (%s --> %s)", key, action);
  590. return -1;
  591. }
  592. KeyboardButton c = stringToKeyboardButton(key);
  593. if (c == unknownKey) {
  594. getConsole().print("bind-Error: Unknown key (%s)", key);
  595. return -2;
  596. }
  597. keyBindings[e] = c;
  598. return 0;
  599. }