/ public_html / script / src / trade.js
trade.js
  1  'use strict';
  2  
  3  import {CONST} from './const.js';
  4  import {default as $} from 'jquery';
  5  import {adjacent} from './adjacent.js';
  6  
  7  const GEN = Symbol(), SOCKET = Symbol(), PLAYER = Symbol();
  8  
  9  export class Trade {
 10      constructor(g, s, p) {
 11          this[GEN] = g;
 12          this[SOCKET] = s;
 13          this[PLAYER] = p;
 14      }
 15  
 16      hideOverlay() {
 17          $('#request-overlay')
 18              .css('display', 'none');
 19          $('#request-form')
 20              .html('');
 21      }
 22  
 23      buttonShow(data) {
 24          if(data.players[this[PLAYER]].hand[CONST.RESOURCE].reduce((p, c) => p + c, 0) > 0) {
 25              $('#init-trade')
 26                  .css('display', 'block')
 27                  .off('click')
 28                  .click(() => {
 29                      this[GEN].next([null, [data, 'trade']]);
 30                  });
 31          }
 32      }
 33      buttonHide() {
 34          $('#init-trade')
 35              .css('display', 'block')
 36              .off('click');
 37      }
 38  
 39      storage(cards) {
 40          this[SOCKET].emit('trade:storage', cards, (err, res) => {
 41              this[GEN].next([err, res]);
 42              this.hideOverlay();
 43          });
 44      }
 45      offer(cards) {
 46          this[SOCKET].emit('trade:offer', cards, (err, res) => {
 47              this[GEN].next([err, res]);
 48          });
 49          $('#request-form')
 50              .html('<h1>Waiting for responses...</h1>');
 51      }
 52      offerShow(data) {
 53          let resourceNames = ['wool', 'wheat', 'wood', 'brick', 'ore'];
 54          let arrangeCards = () => {
 55              $('#to-keep,#to-give,#to-take').each(function() {
 56                  let spacing = 50;
 57                  while(spacing * $(this).children('.card').length > $(this).width()) {
 58                      spacing--;
 59                  }
 60                  $(this).children('.card').each(function(i) {
 61                      $(this).css('left', `${i * spacing}px`);
 62                  });
 63              });
 64              if($('#to-give').children('.card').length >= 1 && $('#to-take').children('.card').length >= 1) {
 65                  $('#trade-button')
 66                      .removeClass('not-clickable');
 67              } else {
 68                  $('#trade-button')
 69                      .addClass('not-clickable');
 70              }
 71  
 72              //Storage validation
 73              let validCount = 0;
 74              let cards = [0,0,0,0,0];
 75              $('#to-give').children('.card')
 76                  .each(function(i) {
 77                      cards[$(this).attr('data-card-type')]++;
 78                  });
 79              let needed = [4,4,4,4,4];
 80              for(let i = 0; i < data.houses.length; i++) {
 81                  for(let j = 0; j < data.houses[i].length; j++) {
 82                      if(data.houses[i][j][1] === this[PLAYER]) {
 83                          let port = adjacent(i, j, 'house', 'port');
 84                          if(port !== null) {
 85                              if(data.ports[port] === CONST.OTHER) {
 86                                  for(let k = 0; k < 5; k++) {
 87                                      needed[k] = Math.min(3, needed[k]);
 88                                  }
 89                              } else {
 90                                  needed[data.ports[port]] = 2;
 91                              }
 92                          }
 93                      }
 94                  }
 95              }
 96              for(let i = 0; i < 5; i++) {
 97                  if(cards[i] % needed[i] === 0) {
 98                      validCount += cards[i] / needed[i];
 99                  } else {
100                      validCount = false;
101                      break;
102                  }
103              }
104              if(validCount && validCount === $('#to-take').children('.card').length) {
105                  $('#storage-button')
106                      .removeClass('not-clickable');
107              } else {
108                  $('#storage-button')
109                      .addClass('not-clickable');
110              }
111          };
112          let addToTake = (res) => () => {
113              $('#to-take')
114                  .append($('<div></div>')
115                      .addClass(`card ${resourceNames[res]}`)
116                      .attr('data-card-type', res)
117                      .css('cursor', 'pointer')
118                      .click(function() {
119                          $(this).remove();
120                          arrangeCards();
121                      })
122                  );
123              arrangeCards();
124          };
125  
126          $('#request-overlay').css('display', 'block');
127          $('#request-form')
128              .append($('<h2></h2>')
129                  .text('Trade')
130              )
131              .append($('<p></p>')
132                  .text('To give')
133              )
134              .append($('<hr>'))
135              .append($('<div></div>')
136                  .addClass('card-container')
137                  .attr('id', 'to-give')
138              )
139              .append($('<p></p>')
140                  .text('Your cards')
141              )
142              .append($('<hr>'))
143              .append($('<div></div>')
144                  .addClass('card-container')
145                  .attr('id', 'to-keep')
146              )
147              .append($('<p></p>')
148                  .text('To take')
149              )
150              .append($('<hr>'))
151              .append($('<div></div>')
152                  .addClass('card-container')
153                  .attr('id', 'to-take')
154              )
155              .append($('<hr>'))
156              .append($('<div></div>')
157                  .addClass('card-container')
158                  .attr('id', 'to-choose')
159                  .append($('<div></div>')
160                      .addClass('resource-container')
161                      .append($('<div></div>')
162                          .addClass('card wool')
163                          .css('cursor', 'pointer')
164                          .click(addToTake(CONST.WOOL))
165                      )
166                      .append($('<div></div>')
167                          .addClass('card wheat')
168                          .css('cursor', 'pointer')
169                          .click(addToTake(CONST.WHEAT))
170                      )
171                      .append($('<div></div>')
172                          .addClass('card wood')
173                          .css('cursor', 'pointer')
174                          .click(addToTake(CONST.WOOD))
175                      )
176                      .append($('<div></div>')
177                          .addClass('card brick')
178                          .css('cursor', 'pointer')
179                          .click(addToTake(CONST.BRICK))
180                      )
181                      .append($('<div></div>')
182                          .addClass('card ore')
183                          .css('cursor', 'pointer')
184                          .click(addToTake(CONST.ORE))
185                      )
186                  )
187              )
188              .append($('<button></button>')
189                  .text('Trade')
190                  .attr('id', 'trade-button')
191                  .click(() => {
192                      let cards = {
193                          give: [0,0,0,0,0],
194                          get: [0,0,0,0,0]
195                      };
196                      $('#to-give').children('.card')
197                          .each(function(i) {
198                              cards.give[$(this).attr('data-card-type')]++;
199                          });
200                      $('#to-take').children('.card')
201                          .each(function(i) {
202                              cards.get[$(this).attr('data-card-type')]++;
203                          });
204                      this.offer(cards);
205                  })
206              )
207              .append($('<button></button>')
208                  .text('Trade with storage')
209                  .attr('id', 'storage-button')
210                  .click(() => {
211                      let cards = {
212                          give: [0,0,0,0,0],
213                          get: [0,0,0,0,0]
214                      };
215                      $('#to-give').children('.card')
216                          .each(function(i) {
217                              cards.give[$(this).attr('data-card-type')]++;
218                          });
219                      $('#to-take').children('.card')
220                          .each(function(i) {
221                              cards.get[$(this).attr('data-card-type')]++;
222                          });
223                      this.storage(cards);
224                  })
225              )
226              .append($('<button></button>')
227                  .text('Cancel')
228                  .click(() => {
229                      this.hideOverlay();
230                      this[GEN].next([null, data]);
231                  })
232              );
233  
234              let hand = new Array(...data.players[this[PLAYER]].hand[CONST.RESOURCE]);
235              let give = $('#to-give');
236              let keep = $('#to-keep');
237  
238              let moveToGive, moveToKeep;
239              moveToKeep = function() {
240                  $(this).detach()
241                      .appendTo(keep)
242                      .off('click')
243                      .click(moveToGive);
244                  arrangeCards();
245              };
246              moveToGive = function() {
247                  $(this).detach()
248                      .appendTo(give)
249                      .off('click')
250                      .click(moveToKeep);
251                  arrangeCards();
252              };
253              for(let i = 0; i < 5; i++) {
254                  for(let j = 0; j < hand[i]; j++) {
255                      keep
256                          .append($('<div></div>')
257                              .addClass(`card ${resourceNames[i]}`)
258                              .css('cursor', 'pointer')
259                              .attr('data-card-type', i)
260                              .click(moveToGive)
261                          );
262                  }
263              }
264              arrangeCards();
265      }
266  
267      respond(offer) {
268          this[SOCKET].emit('trade:respond', offer, (err, res) => {
269              this[GEN].next([err, res]);
270          });
271          this.hideOverlay();
272      }
273      counterOfferShow(data) {
274          let resourceNames = ['wool', 'wheat', 'wood', 'brick', 'ore'];
275          let arrangeCards = () => {
276              $('#to-keep,#to-give,#to-take').each(function() {
277                  let spacing = 50;
278                  while(spacing * $(this).children('.card').length > $(this).width()) {
279                      spacing--;
280                  }
281                  $(this).children('.card').each(function(i) {
282                      $(this).css('left', `${i * spacing}px`);
283                  });
284              });
285              if($('#to-give').children('.card').length >= 1 && $('#to-take').children('.card').length >= 1) {
286                  $('#trade-button')
287                      .removeClass('not-clickable');
288              } else {
289                  $('#trade-button')
290                      .addClass('not-clickable');
291              }
292          };
293  
294          let addToTake = (res) => () => {
295              $('#to-take')
296                  .append($('<div></div>')
297                      .addClass(`card ${resourceNames[res]}`)
298                      .attr('data-card-type', res)
299                      .css('cursor', 'pointer')
300                      .click(function() {
301                          $(this).remove();
302                          arrangeCards();
303                      })
304                  );
305              arrangeCards();
306          };
307  
308          $('#request-overlay').css('display', 'block');
309          $('#request-form')
310              .html('')
311              .css('display', 'block')
312              .append($('<h2></h2>')
313                  .text('Trade')
314              )
315              .append($('<p></p>')
316                  .text('To give')
317              )
318              .append($('<hr>'))
319              .append($('<div></div>')
320                  .addClass('card-container')
321                  .attr('id', 'to-give')
322              )
323              .append($('<p></p>')
324                  .text('Your cards')
325              )
326              .append($('<hr>'))
327              .append($('<div></div>')
328                  .addClass('card-container')
329                  .attr('id', 'to-keep')
330              )
331              .append($('<p></p>')
332                  .text('To take')
333              )
334              .append($('<hr>'))
335              .append($('<div></div>')
336                  .addClass('card-container')
337                  .attr('id', 'to-take')
338              )
339              .append($('<hr>'))
340              .append($('<div></div>')
341                  .addClass('card-container')
342                  .attr('id', 'to-choose')
343                  .append($('<div></div>')
344                      .addClass('resource-container')
345                      .append($('<div></div>')
346                          .addClass('card wool')
347                          .css('cursor', 'pointer')
348                          .click(addToTake(CONST.WOOL))
349                      )
350                      .append($('<div></div>')
351                          .addClass('card wheat')
352                          .css('cursor', 'pointer')
353                          .click(addToTake(CONST.WHEAT))
354                      )
355                      .append($('<div></div>')
356                          .addClass('card wood')
357                          .css('cursor', 'pointer')
358                          .click(addToTake(CONST.WOOD))
359                      )
360                      .append($('<div></div>')
361                          .addClass('card brick')
362                          .css('cursor', 'pointer')
363                          .click(addToTake(CONST.BRICK))
364                      )
365                      .append($('<div></div>')
366                          .addClass('card ore')
367                          .css('cursor', 'pointer')
368                          .click(addToTake(CONST.ORE))
369                      )
370                  )
371              )
372              .append($('<button></button>')
373                  .text('Send offer')
374                  .attr('id', 'trade-button')
375                  .click(() => {
376                      let cards = {
377                          give: [0,0,0,0,0],
378                          get: [0,0,0,0,0]
379                      };
380                      $('#to-give').children('.card')
381                          .each(function(i) {
382                              cards.get[$(this).attr('data-card-type')]++;
383                          });
384                      $('#to-take').children('.card')
385                          .each(function(i) {
386                              cards.give[$(this).attr('data-card-type')]++;
387                          });
388                      this.respond(cards);
389                  })
390              )
391              .append($('<button></button>')
392                  .text('Cancel (reject)')
393                  .click(() => {
394                      this.respond({response: false});
395                  })
396              );
397  
398              let hand = new Array(...data.players[this[PLAYER]].hand[CONST.RESOURCE]);
399              let give = $('#to-give');
400              let keep = $('#to-keep');
401              let take = $('#to-take');
402  
403              let moveToGive, moveToKeep;
404              moveToKeep = function() {
405                  $(this).detach()
406                      .appendTo(keep)
407                      .off('click')
408                      .click(moveToGive);
409                  arrangeCards();
410              };
411              moveToGive = function() {
412                  $(this).detach()
413                      .appendTo(give)
414                      .off('click')
415                      .click(moveToKeep);
416                  arrangeCards();
417              };
418              for(let i = 0; i < 5; i++) {
419                  for(let j = 0; j < data.trade.get[i]; j++) {
420                      if(hand[i]) {
421                          give
422                              .append($('<div></div>')
423                                  .addClass(`card ${resourceNames[i]}`)
424                                  .css('cursor', 'pointer')
425                                  .attr('data-card-type', i)
426                                  .click(moveToKeep)
427                              );
428                          hand[i]--;
429                      }
430                  }
431              }
432              for(let i = 0; i < 5; i++) {
433                  for(let j = 0; j < data.trade.give[i]; j++) {
434                      take
435                          .append($('<div></div>')
436                              .addClass(`card ${resourceNames[i]}`)
437                              .css('cursor', 'pointer')
438                              .attr('data-card-type', i)
439                              .click(function() {
440                                  $(this).remove();
441                                  arrangeCards();
442                              })
443                          );
444                  }
445              }
446              for(let i = 0; i < hand.length; i++) {
447                  for(let j = 0; j < hand[i]; j++) {
448                      keep
449                          .append($('<div></div>')
450                              .addClass(`card ${resourceNames[i]}`)
451                              .css('cursor', 'pointer')
452                              .attr('data-card-type', i)
453                              .click(moveToGive)
454                          );
455                  }
456              }
457              arrangeCards();
458      }
459      counter(data) {
460          let arrangeCards = () => {
461              $('#to-give,#to-take').each(function() {
462                  let spacing = 50;
463                  while(spacing * $(this).children('.card').length > $(this).width()) {
464                      spacing--;
465                  }
466                  $(this).children('.card').each(function(i) {
467                      $(this).css('left', `${i * spacing}px`);
468                  });
469              });
470          };
471          $('#request-overlay').css('display', 'block');
472          $('#request-form')
473              .append($('<h2></h2>')
474                  .text(`Trade offer from ${data.trade.player}`)
475              )
476              .append($('<p></p>')
477                  .text('You give')
478              )
479              .append($('<hr>'))
480              .append($('<div></div>')
481                  .addClass('card-container')
482                  .attr('id', 'to-give')
483              )
484              .append($('<p></p>')
485                  .text('You get')
486              )
487              .append($('<hr>'))
488              .append($('<div></div>')
489                  .addClass('card-container')
490                  .attr('id', 'to-take')
491              )
492              .append($('<button></button>')
493                  .text('Accept')
494                  .attr('id', 'accept-button')
495                  .click(() => {
496                      this.respond({response: true});
497                  })
498              )
499              .append($('<button></button>')
500                  .text('Reject')
501                  .click(() => {
502                      this.respond({response: false});
503                  })
504              )
505              .append($('<button></button>')
506                  .text('Make a counter offer')
507                  .click(() => {
508                      this.counterOfferShow(data);
509                  })
510              );
511              let take = $('#to-take');
512              let give = $('#to-give');
513              let resourceNames = ['wool', 'wheat', 'wood', 'brick', 'ore'];
514              for(let i = 0; i < 5; i++) {
515                  if(data.trade.get[i] > data.players[this[PLAYER]].hand[CONST.RESOURCE][i]) {
516                      $('#accept-button')
517                          .addClass('not-clickable');
518                  }
519                  for(let j = 0; j < data.trade.get[i]; j++) {
520                      give
521                          .append($('<div></div>')
522                              .addClass(`card ${resourceNames[i]}`)
523                          );
524                  }
525                  for(let j = 0; j < data.trade.give[i]; j++) {
526                      take
527                          .append($('<div></div>')
528                              .addClass(`card ${resourceNames[i]}`)
529                          );
530                  }
531              }
532              arrangeCards();
533      }
534      reject() {
535          this[SOCKET].emit('trade:reject', null, (err, res) => {
536              this[GEN].next([err, res]);
537          });
538          this.hideOverlay();
539      }
540      accept(name) {
541          this[SOCKET].emit('trade:accept', name, (err, res) => {
542              this[GEN].next([err, res]);
543          });
544          this.hideOverlay();
545      }
546  
547      offersShow(data) {
548          let resourceNames = ['wool', 'wheat', 'wood', 'brick', 'ore'];
549          $('#request-overlay').css('display', 'block');
550          let form = $('#request-form')
551              .html('')
552              .append($('<h2></h2>')
553                  .text('Choose an offer')
554              );
555          for(let name in data.players) {
556              if(name !== this[PLAYER]) {
557                  if(data.players[name].response.trade.response === false) {
558                      form
559                          .append($('<div></div>')
560                              .addClass('trade-offer')
561                              .append($('<h2></h2>')
562                                  .text(`${name} rejected your offer`)
563                              )
564                          );
565                  } else if(data.players[name].response.trade.response === true) {
566                      form
567                          .append($('<div></div>')
568                              .addClass('trade-offer')
569                              .append($('<h2></h2>')
570                                  .text(`${name} accepted your offer`)
571                              )
572                              .append($('<div></div>')
573                                  .addClass('trade-left')
574                                  .append($('<p></p>')
575                                      .text('Give')
576                                  )
577                                  .append($('<div></div>')
578                                      .addClass('card-container small')
579                                      .attr('id', `for-${name}`)
580                                  )
581                                  .append($('<p></p>')
582                                      .text('Get')
583                                  )
584                                  .append($('<div></div>')
585                                      .addClass('card-container small')
586                                      .attr('id', `from-${name}`)
587                                  )
588                              )
589                              .append($('<button></button>')
590                                  .text('Accept')
591                                  .click(() => {
592                                      this.accept(name);
593                                  })
594                              )
595                          );
596                          let give = $(`#for-${name}`);
597                          let get = $(`#from-${name}`);
598                          for(let i = 0; i < 5; i++) {
599                              for(let j = 0; j < data.trade.give[i]; j++) {
600                                  give
601                                      .append($('<div></div>')
602                                      .addClass(`card ${resourceNames[i]}`)
603                                  );
604                              }
605                              for(let j = 0; j < data.trade.get[i]; j++) {
606                                  get
607                                      .append($('<div></div>')
608                                      .addClass(`card ${resourceNames[i]}`)
609                                  );
610                              }
611                          }
612                  } else {
613                      form
614                          .append($('<div></div>')
615                              .addClass('trade-offer')
616                              .append($('<h2></h2>')
617                                  .text(`${name} offers:`)
618                              )
619                              .append($('<div></div>')
620                                  .addClass('trade-left')
621                                  .append($('<p></p>')
622                                      .text('Give')
623                                  )
624                                  .append($('<div></div>')
625                                      .addClass('card-container small')
626                                      .attr('id', `for-${name}`)
627                                  )
628                                  .append($('<p></p>')
629                                      .text('Get')
630                                  )
631                                  .append($('<div></div>')
632                                      .addClass('card-container small')
633                                      .attr('id', `from-${name}`)
634                                  )
635                              )
636                              .append($('<button></button>')
637                                  .text('Accept')
638                                  .click(() => {
639                                      this.accept(name);
640                                  })
641                              )
642                          );
643                          let give = $(`#for-${name}`);
644                          let get = $(`#from-${name}`);
645                          for(let i = 0; i < 5; i++) {
646                              for(let j = 0; j < data.players[name].response.trade.give[i]; j++) {
647                                  give
648                                      .append($('<div></div>')
649                                      .addClass(`card ${resourceNames[i]}`)
650                                  );
651                              }
652                              for(let j = 0; j < data.players[name].response.trade.get[i]; j++) {
653                                  get
654                                      .append($('<div></div>')
655                                      .addClass(`card ${resourceNames[i]}`)
656                                  );
657                              }
658                          }
659                  }
660              }
661          }
662          form.append($('<button></button>')
663              .text('Accept none')
664              .click(() => {
665                  this.reject();
666              })
667          );
668          $('.card-container').each(function() {
669              let spacing = 25;
670              while(spacing * $(this).children('.card').length > $(this).width()) {
671                  spacing--;
672              }
673              $(this).children('.card').each(function(i) {
674                  $(this).css('left', `${i * spacing}px`);
675              });
676          });
677      }
678  }