Skip to content

Commit

Permalink
Regenerative fight points #104
Browse files Browse the repository at this point in the history
  • Loading branch information
niqore committed Aug 4, 2020
1 parent 8225d12 commit 2b7bdcb
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 7 deletions.
6 changes: 6 additions & 0 deletions database/migrations/006-fight-points.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-- Up

ALTER TABLE entities ADD fightPointsLost INTEGER;
UPDATE entities SET fightPointsLost = 0;

-- Down
8 changes: 8 additions & 0 deletions ressources/text/commands/fight.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
"direct": "{pseudo}, vous ne pouvez pas lancer de combat lorsque vous êtes occupé !",
"indirect": "Cette personne est occupée pour le moment !"
},
"noFightPoints": {
"direct": "{pseudo}, vous n'avez plus de points de combat !",
"indirect": "Cette personne n'a plus de points de combat !"
},
"defenderDoesntExist": "La personne demandée n'existe pas !"
},
"actions": {
Expand Down Expand Up @@ -159,6 +163,10 @@
"direct": "{pseudo}, you can't start a fight if you're occupied !",
"indirect": "This person is currently occupied !"
},
"noFightPoints": {
"direct": "{pseudo}, you don't have any fight points !",
"indirect": "This person doesn't have any fight points !"
},
"defenderDoesntExist": "Asked player doesn't exist!"
},
"actions": {
Expand Down
4 changes: 2 additions & 2 deletions ressources/text/commands/help.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"fight": {
"emote": ":crossed_swords:",
"usage": "fight",
"description": "Utilisez cette commande pour défier les autres joueurs qui se trouvent sur le même serveur que vous.\nLes combats se déroulent tour par tour. À chaque tour, vous pouvez choisir une action à effectuer.\n\nVoici la liste des actions:\n- :crossed_swords: **Attaque simple**: Une attaque moyenne qui a des chances moyennes de réussir.\n- :dagger: **Attaque rapide**: Une attaque qui marche bien si vous êtes plus rapide que votre adversaire.\n- :axe: **Attaque puissante**: Une attaque avec peu de réussite mais qui fait beaucoup de dégâts.\n- :bomb: **Attaque ultime**: Une attaque sur 2 tours, qui est efficace si vous avez moins de défense que votre adversaire. Elle enlève 2/3 de la vie de votre adversaire.\n- :shield: **Défense**: Augmente la défense. La défense permet de prendre moins de dégâts des attaques. Plus l'action est utilisée, moins elle est efficace.\n- :rocket: **Vitesse**: Augmente la vitesse. Si votre vitesse est supérieure à celle de votre adversaire, vous avez plus de chance de réussir votre attaque sauf pour l'attaque ultime. Plus l'action est utilisée, moins elle est efficace.\n\nLe combat s'arrête quand un joueur n'a plus de vie, ne répond pas au bout de 30 secondes ou que le tour 25 est atteint."
"description": "Utilisez cette commande pour défier les autres joueurs qui se trouvent sur le même serveur que vous.\nLes combats se déroulent tour par tour. À chaque tour, vous pouvez choisir une action à effectuer.\n\nVoici la liste des actions:\n- :crossed_swords: **Attaque simple**: Une attaque moyenne qui a des chances moyennes de réussir.\n- :dagger: **Attaque rapide**: Une attaque qui marche bien si vous êtes plus rapide que votre adversaire.\n- :axe: **Attaque puissante**: Une attaque avec peu de réussite mais qui fait beaucoup de dégâts.\n- :bomb: **Attaque ultime**: Une attaque sur 2 tours, qui est efficace si vous avez moins de défense que votre adversaire. Elle enlève 2/3 de la vie de votre adversaire.\n- :shield: **Défense**: Augmente la défense. La défense permet de prendre moins de dégâts des attaques. Plus l'action est utilisée, moins elle est efficace.\n- :rocket: **Vitesse**: Augmente la vitesse. Si votre vitesse est supérieure à celle de votre adversaire, vous avez plus de chance de réussir votre attaque sauf pour l'attaque ultime. Plus l'action est utilisée, moins elle est efficace.\n\nLe combat s'arrête quand un joueur n'a plus de vie, ne répond pas au bout de 30 secondes ou que le tour 25 est atteint. Quand un combat se finit, vous allez probablement perdre des points. Ils se régénèrent avec le temps."
},
"friendlyfight": {
"emote": ":crossed_swords:",
Expand Down Expand Up @@ -181,7 +181,7 @@
"fight": {
"emote": ":crossed_swords:",
"usage": "fight",
"description": "Use this command to duel other players on the same server as you.\nFights are turn-based. Each turn, you can choose an action.\n\nHere's the action list:\n- :crossed_swords: **Basic attack**: A balanced attack with a medium success rate.\n- :dagger: **Quick attack**: An attack efficient if you are faster than your opponent.\n- :axe: **Powerful attack**: A low success rate attack, but which deals a lot of damage.\n- :bomb: **Supreme attack**: A 2 turns attack, which is efficient only if your speed is lower than your opponent's one. When successful, it decreases 2/3 of your opponent's life.\n- :shield: **Defense**: Increases your defense. The more defense you have, the less damage you take. Moreover, the more you use this action, the less defense you'll get.\n- :rocket: **Speed**: Increases your speed. Attacks have a higher success rate if your speed is greater than your opponent's one, except for the supreme attack. Moreover, the more you use this action, the less speed you'll get.\n\nThe fight ends when a fighter's life drops to 0, doesn't answer after 30 seconds or when the turn number 25 is reached."
"description": "Use this command to duel other players on the same server as you.\nFights are turn-based. Each turn, you can choose an action.\n\nHere's the action list:\n- :crossed_swords: **Basic attack**: A balanced attack with a medium success rate.\n- :dagger: **Quick attack**: An attack efficient if you are faster than your opponent.\n- :axe: **Powerful attack**: A low success rate attack, but which deals a lot of damage.\n- :bomb: **Supreme attack**: A 2 turns attack, which is efficient only if your speed is lower than your opponent's one. When successful, it decreases 2/3 of your opponent's life.\n- :shield: **Defense**: Increases your defense. The more defense you have, the less damage you take. Moreover, the more you use this action, the less defense you'll get.\n- :rocket: **Speed**: Increases your speed. Attacks have a higher success rate if your speed is greater than your opponent's one, except for the supreme attack. Moreover, the more you use this action, the less speed you'll get.\n\nThe fight ends when a fighter's life drops to 0, doesn't answer after 30 seconds or when the turn number 25 is reached. When the fight ends, you'll probably lost fight points. They will be recovered over time."
},
"friendlyfight": {
"emote": ":crossed_swords:",
Expand Down
7 changes: 7 additions & 0 deletions src/commands/admin/TestCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,13 @@ const TestCommand = async(language, message, args) => {
author.Player.topggVoteAt -= parseInt(args[1]) * 60000;
author.Player.save();
break;
case 'fightpointslost':
case 'fpl':
if (args.length === 2) {
author.fightPointsLost = parseInt(args[1]);
author.save();
}
break;
default:
await message.channel.send('Argument inconnu !');
return;
Expand Down
19 changes: 15 additions & 4 deletions src/commands/player/FightCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ const FightCommand = async function(language, message, args, friendly = false) {

let isTournament = tournamentChannel === message.channel.id;
let canF;
if ((canF = canFight(attacker, isTournament)) !== FIGHT_ERROR.NONE) {
if ((canF = canFight(attacker, isTournament, friendly || isTournament)) !== FIGHT_ERROR.NONE) {
sendError(message, attacker, canF, true, language);
return;
}
if (defender != null && (canF = canFight(defender, isTournament)) !== FIGHT_ERROR.NONE) {
if (defender != null && (canF = canFight(defender, isTournament, friendly || isTournament)) !== FIGHT_ERROR.NONE) {
sendError(message, defender, canF, false, language);
return;
}
Expand Down Expand Up @@ -96,7 +96,7 @@ const FightCommand = async function(language, message, args, friendly = false) {
break;
}
[defender] = await Entities.getOrRegister(user.id);
if ((canF = canFight(defender, isTournament)) !== FIGHT_ERROR.NONE) {
if ((canF = canFight(defender, isTournament, friendly || isTournament)) !== FIGHT_ERROR.NONE) {
sendError(message, defender, canF, true, language);
defender = null;
return;
Expand Down Expand Up @@ -169,6 +169,12 @@ function sendError(message, entity, error, direct, language) {
JsonReader.commands.fight.getTranslation(language).error.occupied.indirect;
sendErrorMessage(message.guild.members.cache.get(entity.discordUser_id).user, message.channel, language, msg2);
break;
case FIGHT_ERROR.NO_FIGHT_POINTS:
const msg3 = direct ?
format(JsonReader.commands.fight.getTranslation(language).error.noFightPoints.direct, {pseudo: entity.getMention()}) :
JsonReader.commands.fight.getTranslation(language).error.noFightPoints.indirect;
sendErrorMessage(message.guild.members.cache.get(entity.discordUser_id).user, message.channel, language, msg3);
break;
default:
break;
}
Expand All @@ -177,9 +183,10 @@ function sendError(message, entity, error, direct, language) {
/**
* @param entity
* @param {boolean} bypassAlteration
* @param {boolean} bypassHealth
* @return {Number} error
*/
function canFight(entity, bypassAlteration) {
function canFight(entity, bypassAlteration, bypassHealth) {
if (entity == null) {
return null;
}
Expand All @@ -192,6 +199,9 @@ function canFight(entity, bypassAlteration) {
if (global.hasBlockedPlayer(entity.discordUser_id)) {
return FIGHT_ERROR.OCCUPIED;
}
if (entity.getCumulativeHealth() === 0 && !bypassHealth) {
return FIGHT_ERROR.NO_FIGHT_POINTS;
}
return 0;
}

Expand Down Expand Up @@ -231,6 +241,7 @@ const FIGHT_ERROR = {
WRONG_LEVEL: 1,
DISALLOWED_EFFECT: 2,
OCCUPIED: 3,
NO_FIGHT_POINTS: 4
};

/**
Expand Down
2 changes: 2 additions & 0 deletions src/core/Constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ global.FIGHT = {
MAX_SPEED_IMPROVEMENT: 30,
MAX_TURNS: 25,
REQUIRED_LEVEL: 8,
POINTS_REGEN_MINUTES: 15,
POINTS_REGEN_AMOUNT: 50,
ACTION: {
QUICK_ATTACK: 0,
SIMPLE_ATTACK: 1,
Expand Down
7 changes: 7 additions & 0 deletions src/core/DraftBot.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class DraftBot {
// draftbot.checkEasterEggsFile();

DraftBot.programTopWeekTimeout();
setTimeout(DraftBot.fightPowerRegenerationLoop, FIGHT.POINTS_REGEN_MINUTES*60*1000);

require('core/DBL').startDBLWebhook();

Expand Down Expand Up @@ -79,6 +80,12 @@ class DraftBot {
DraftBot.programTopWeekTimeout();
}

static async fightPowerRegenerationLoop() {
const sequelize = require('sequelize');
await Entities.update({ fightPointsLost: sequelize.literal(`CASE WHEN fightPointsLost - ${FIGHT.POINTS_REGEN_AMOUNT} < 0 THEN 0 ELSE fightPointsLost - ${FIGHT.POINTS_REGEN_AMOUNT} END`)}, {where: { fightPointsLost: {[sequelize.Op.not]: 0}}});
setTimeout(DraftBot.fightPowerRegenerationLoop, FIGHT.POINTS_REGEN_MINUTES*60*1000);
}

/**
* TODO 2.1
* Checks if the easter eggs file exists and copy the default one if not
Expand Down
6 changes: 6 additions & 0 deletions src/core/Fight.js
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,12 @@ class Fight {
winner.entity.Player.addWeeklyScore(this.points);
winner.entity.Player.save();
}
if (!this.friendly && !this.tournamentMode) {
for (let i = 0; i < this.fighters.length; i++) {
this.fighters[i].entity.fightPointsLost = this.fighters[i].entity.getMaxCumulativeHealth() - this.fighters[i].power;
this.fighters[i].entity.save();
}
}
for (let i = 0; i < this.fighters.length; i++) {
global.removeBlockedPlayer(this.fighters[i].entity.discordUser_id);
}
Expand Down
8 changes: 7 additions & 1 deletion src/core/models/Entities.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ module.exports = (Sequelize, DataTypes) => {
type: DataTypes.DATE,
defaultValue: require('moment')().format('YYYY-MM-DD HH:mm:ss'),
},
fightPointsLost: {
type: DataTypes.INTEGER,
defaultValue: 0
}
}, {
tableName: 'entities',
freezeTableName: true,
Expand Down Expand Up @@ -221,7 +225,9 @@ module.exports = (Sequelize, DataTypes) => {
* @return {Number}
*/
Entities.prototype.getCumulativeHealth = function() {
return this.maxHealth + (this.Player.level * 10);
let fp = this.getMaxCumulativeHealth() - this.fightPointsLost;
if (fp < 0) fp = 0;
return fp;
};

/**
Expand Down

0 comments on commit 2b7bdcb

Please sign in to comment.