// Copyright 2019 Campbell Crowley. All rights reserved.
// Author: Campbell Crowley (dev@campbellcrowley.com)
const UserIconUrl = require('./UserIconUrl.js');
const Grammar = require('./Grammar.js');
const funTranslator = require('../lib/funTranslators.js');
/**
* @description Finalized event ready for display to users.
* @memberof HungryGames
* @inner
*/
class FinalEvent {
/**
* @description Create an event ready for display.
* @param {HungryGames~NormalEvent} evt Event to finalize.
* @param {HungryGames~GuildGame} game Game context.
* @param {HungryGames~Player[]} affected An array of all players affected by
* this event.
*/
constructor(evt, game, affected) {
const useNickname = game.options.useNicknames ? 'nickname' : 'username';
const mention = game.options.mentionAll;
const vO = evt.victim.outcome;
const aO = evt.attacker.outcome;
const nV = evt.victim.count;
const nA = evt.attacker.count;
/**
* @description String to send to mention users.
* @public
* @type {string}
*/
this.mentionString = '';
let translator = null;
for (let i = 0; i < affected.length; i++) {
if (!affected[i]) {
console.log('BAD AFFECTED', affected);
continue;
}
if (!affected[i].isNPC && mention == 'all' ||
(mention == 'death' &&
((vO == 'dies' && i < nV) || (aO == 'dies' && i >= nV)))) {
this.mentionString += `<@${affected[i].id}>`;
}
if (affected[i].settings &&
affected[i].settings['hg:fun_translators'] &&
affected[i].settings['hg:fun_translators'] !== 'disabled') {
translator = affected[i].settings['hg:fun_translators'];
}
}
const affectedVictims = affected.slice(0, nV);
const affectedAttackers = affected.slice(nV, nA + nV);
let finalMessage =
evt.message
.replace(
/\[V([^|]*)\|([^\]]*)\]/g,
affectedVictims.length > 1 ? '$2' : '$1')
.replace(
/\[A([^|]*)\|([^\]]*)\]/g,
affectedAttackers.length > 1 ? '$2' : '$1');
let deadUsers = [];
if (finalMessage.indexOf('{dead}') > -1) {
const deadList = game.currentGame.includedUsers.filter(
(obj) => !obj.living && !affected.find((u) => u.id == obj.id));
if (deadList.length > 0) {
const index = Math.floor(Math.random() * deadList.length);
deadUsers = deadList.slice(index, index + 1);
}
finalMessage = finalMessage.replace(
/\[D([^|]*)\|([^\]]*)\]/g, deadUsers.length <= 1 ? '$1' : '$2');
}
finalMessage =
finalMessage.replace(/\{(victim|attacker|dead)\}/g, (match, tag) => {
switch (tag) {
case 'victim':
return Grammar.formatMultiNames(affectedVictims, useNickname);
case 'attacker':
return Grammar.formatMultiNames(affectedAttackers, useNickname);
case 'dead':
if (deadUsers.length > 0) {
return Grammar.formatMultiNames(deadUsers, useNickname);
} else {
return 'an animal';
}
}
});
finalMessage = funTranslator.to(translator, finalMessage);
/**
* @description Message to show to user.
* @public
* @type {string}
*/
this.message = finalMessage;
/**
* @description The icons to show in the message.
* @public
* @type {HungryGames~UserIconUrl[]}
*/
this.icons = UserIconUrl.from(affectedVictims, affectedAttackers);
/**
* @description Amount of weapons this consumes.
* @public
* @type {Array.<{name: string, count: number}>}
*/
this.consumes = evt.consumes;
if (!evt.consumes || typeof evt.consumes === 'number' ||
(typeof evt.consumes === 'string' && evt.consumes.match(/^\d+$/))) {
if (evt.consumes != null) {
this.consumes = [evt.consumes * 1];
} else {
this.consumes = [];
}
} else if (!Array.isArray(this.consumes)) {
throw new TypeError('Consumes is not an array: ' + evt.consumes);
}
/**
* @description The ID of the player that will be consuming weapons.
* @public
* @type {string}
*/
this.consumer = evt.consumer;
const vW = evt.victim.weapon &&
[{id: evt.victim.weapon.id, count: evt.victim.weapon.count}];
const aW = evt.attacker.weapon &&
[{id: evt.attacker.weapon.id, count: evt.attacker.weapon.count}];
/**
* @description Information about the victims as a result of this event.
* Weapon count is amount gained.
* @public
* @type {{
* outcome: string,
* count: number,
* killer: boolean,
* weapons: Array.<{name: string, count: number}>
* }}
*/
this.victim = {
outcome: vO,
count: nV,
killer: evt.victim.killer,
weapons: vW || [],
};
/**
* @description Information about the attackers as a result of this event.
* Weapon count is amount gained.
* @public
* @type {{
* outcome: string,
* count: number,
* killer: boolean,
* weapons: Array.<{name: string, count: number}>
* }}
*/
this.attacker = {
outcome: aO,
count: nA,
killer: evt.attacker.killer,
weapons: aW || [],
};
/**
* @description Additional message text to display.
* @public
* @type {string}
*/
this.subMessage = evt.subMessage || '';
}
}
module.exports = FinalEvent;