Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

202 linhas
4.4 KiB

  1. module.exports = {
  2. type: 'dialogue',
  3. states: {},
  4. sourceStates: {},
  5. trigger: null,
  6. init: function (blueprint) {
  7. this.states = blueprint.config;
  8. },
  9. destroy: function () {
  10. if (this.trigger)
  11. this.trigger.destroyed = true;
  12. },
  13. talk: function (msg) {
  14. if (!msg)
  15. return false;
  16. let target = msg.target;
  17. if (!target && !msg.targetName)
  18. return false;
  19. if (target && !target.id) {
  20. target = this.obj.instance.objects.objects.find(o => o.id === target);
  21. if (!target)
  22. return false;
  23. } else if (msg.targetName) {
  24. target = this.obj.instance.objects.objects.find(o => ((o.name) && (o.name.toLowerCase() === msg.targetName.toLowerCase())));
  25. if (!target)
  26. return false;
  27. }
  28. if (!target.dialogue)
  29. return false;
  30. //Auto-discover faction
  31. if ((target.trade) && (target.trade.faction))
  32. this.obj.reputation.discoverFaction(target.trade.faction.id);
  33. let state = target.dialogue.getState(this.obj, msg.state);
  34. if (!state) {
  35. this.obj.syncer.set(true, 'dialogue', 'state', null);
  36. return false;
  37. }
  38. this.obj.syncer.set(true, 'dialogue', 'state', state);
  39. },
  40. stopTalk: function () {
  41. this.obj.syncer.set(true, 'dialogue', 'state', null);
  42. },
  43. getState: function (sourceObj, state = 1) {
  44. let result = null;
  45. if ((state + '').indexOf('.') > -1) {
  46. let config = this.states[(state + '').split('.')[0]];
  47. if (!config)
  48. return false;
  49. let goto = (config.options[state] || {}).goto;
  50. if (goto instanceof Array) {
  51. let gotos = [];
  52. goto.forEach(function (g) {
  53. let rolls = (g.chance * 100) || 100;
  54. for (let i = 0; i < rolls; i++)
  55. gotos.push(g.number);
  56. });
  57. state = gotos[~~(Math.random() * gotos.length)];
  58. } else
  59. state = goto;
  60. }
  61. this.sourceStates[sourceObj.id] = state;
  62. if (!this.states)
  63. return null;
  64. let stateConfig = this.states[state];
  65. if (!stateConfig)
  66. return null;
  67. let useMsg = stateConfig.msg;
  68. if (stateConfig.cpn) {
  69. let cpn = sourceObj[stateConfig.cpn];
  70. let newArgs = extend([], stateConfig.args);
  71. newArgs.push(this.obj);
  72. result = cpn[stateConfig.method].apply(cpn, newArgs);
  73. if (stateConfig.goto) {
  74. if (result)
  75. return this.getState(sourceObj, stateConfig.goto.success);
  76. return this.getState(sourceObj, stateConfig.goto.failure);
  77. }
  78. if (result) {
  79. useMsg = extend([], useMsg);
  80. useMsg[0].msg = result;
  81. } else
  82. return null;
  83. } else if (stateConfig.method) {
  84. let methodResult = stateConfig.method.call(this.obj, sourceObj);
  85. if (methodResult) {
  86. useMsg = extend([], useMsg);
  87. useMsg[0].msg = methodResult;
  88. }
  89. if (!useMsg)
  90. return;
  91. }
  92. result = {
  93. id: this.obj.id,
  94. msg: null,
  95. from: this.obj.name,
  96. options: []
  97. };
  98. if (useMsg instanceof Array) {
  99. let msgs = [];
  100. useMsg.forEach(function (m, i) {
  101. let rolls = (m.chance * 100) || 100;
  102. for (let j = 0; j < rolls; j++) {
  103. msgs.push({
  104. msg: m,
  105. index: i
  106. });
  107. }
  108. });
  109. let pick = msgs[~~(Math.random() * msgs.length)];
  110. result.msg = pick.msg.msg;
  111. result.options = useMsg[pick.index].options;
  112. } else {
  113. result.msg = useMsg;
  114. result.options = stateConfig.options;
  115. }
  116. if (!(result.options instanceof Array)) {
  117. if (result.options[0] === '$')
  118. result.options = this.states[result.options.replace('$', '')].options;
  119. result.options = Object.keys(result.options);
  120. }
  121. result.options = result.options
  122. .map(function (o) {
  123. let gotoState = this.states[(o + '').split('.')[0]];
  124. let picked = gotoState.options[o];
  125. if (!picked)
  126. return null;
  127. else if (picked.prereq) {
  128. let doesConform = picked.prereq(sourceObj);
  129. if (!doesConform)
  130. return null;
  131. }
  132. return {
  133. id: o,
  134. msg: picked.msg
  135. };
  136. }, this)
  137. .filter(o => !!o);
  138. result.options.push({
  139. msg: 'Goodbye',
  140. id: 999
  141. });
  142. return result;
  143. },
  144. simplify: function (self) {
  145. return {
  146. type: 'dialogue'
  147. };
  148. },
  149. //These don't belong here, but I can't figure out where to put them right now
  150. //They are actions that can be performed while chatting with someone
  151. teleport: function (msg) {
  152. this.obj.syncer.set(true, 'dialogue', 'state', null);
  153. let portal = extend({}, require('./portal'), msg);
  154. portal.collisionEnter(this.obj);
  155. },
  156. getItem: function (msg, source) {
  157. let inventory = this.obj.inventory;
  158. let exists = inventory.items.find(i => (i.name === msg.item.name));
  159. if (!exists) {
  160. inventory.getItem(msg.item);
  161. return msg.successMsg || false;
  162. } return msg.existsMsg || false;
  163. }
  164. };