Skip to content

Commit

Permalink
Added forfeiting of online battles
Browse files Browse the repository at this point in the history
This fixes #192. It will probably require a fair bit of testing.
  • Loading branch information
varkor committed Jan 5, 2016
1 parent e097fec commit 2282f38
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 21 deletions.
116 changes: 96 additions & 20 deletions battle/scripts/objects/general/BattleContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,11 @@ function BattleContext (client) {
if (battleContext.escape(currentBattler))
advance = false;
break;
case "Forfeit":
battleContext.forfeitBattle();
advance = false;
reprompt = false;
break;
case "Back":
var previous = battleContext.actions.pop();
if (previous.hasOwnProperty("undo"))
Expand Down Expand Up @@ -1326,6 +1331,8 @@ function BattleContext (client) {
actionsForTrainers[communication.trainer] = 0;
}
++ actionsForTrainers[communication.trainer];
} else if (communication.action === "forfeit") {
actionsForTrainers[communication.trainer] = requiredActions[communication.trainer];
}
});
var waitingFor = [];
Expand Down Expand Up @@ -1371,7 +1378,12 @@ function BattleContext (client) {
character : {}, // Relative to `character`
pokemon : {} // Relative to `battleContext.allTrainers()`
};
var skipOtherActions = false;
var isValid = (battleContext.state.kind === "waiting" && !foreach(actions, function (action) {
if (skipOtherActions) {
issues.push("Too many actions have been sent.");
return true; // We've received too many actions!
}
if (["command"].contains(battleContext.state.for)) {
if (selection >= inBattle.length) {
issues.push("Too many actions have been sent.");
Expand All @@ -1381,6 +1393,15 @@ function BattleContext (client) {
}
if (!requireProperty(action, "trainer") || !requireProperty(action, "action")) // The `trainer` parameter is effectively guaranteed because Supervisor adds it itself, so we don't need to check that they all match up
return true;
if (action.action === "forfeit") {
if (!battleContext.isCompetitiveBattle()) {
issues.push("The player tried to forfeit a non-PvP battle.");
return true; // Can only forfeit in certain situations
} else {
skipOtherActions = true;
return false;
}
}
switch (battleContext.state.for) {
case "command":
if (!requireProperty(action, "primary") || typeof action.primary !== "string" || !["Fight", "Bag", "Pokémon", "Run"].contains(action.primary))
Expand Down Expand Up @@ -1534,7 +1555,7 @@ function BattleContext (client) {
// It has passed all the checks, so can be Mega Evolved
preservation.character.megaEvolution = character.megaEvolution;
character.megaEvolution = currentBattler;
}
}
break;
case "send":
if (!requireProperty(action, "which") || !isNaturalNumber(action, "which", character.healthyEligiblePokemon(true).length))
Expand Down Expand Up @@ -1624,9 +1645,47 @@ function BattleContext (client) {
receiveActions : function (actions) {
// Receive the opponent's actions, in an online battle
if (actions.notEmpty()) {
battleContext.communication = battleContext.communication.concat(actions);
if (battleContext.state.kind === "waiting" && battleContext.hasCommunicationForTrainers(battleContext.state.for)) {
battleContext.state.response();
var forfeiters = [];
foreach(actions, action => {
if (action.action === "forfeit") {
forfeiters.push(action.trainer);
}
});
if (forfeiters.empty()) {
battleContext.communication = battleContext.communication.concat(actions);
if (battleContext.state.kind === "waiting" && battleContext.hasCommunicationForTrainers(battleContext.state.for)) {
battleContext.state.response();
}
} else {
var endBattleFlags;
if (forfeiters.length === 1 && forfeiters.first() === battleContext.opposingTrainers.first().identification) {
if (!battleContext.process) {
var opponents = [];
foreach(battleContext.opposingTrainers, function (opposer) {
opponents.push(opposer.fullname());
});
Textbox.state(opponents + " forfeited the battle!");
}
endBattleFlags = {
"outcome" : "allied victory"
};
} else if (forfeiters.length === 1 && forfeiters.first() === battleContext.alliedTrainers.first().identification) {
if (!battleContext.process) {
var playerName = !battleContext.process ? battleContext.alliedTrainers.first().pronoun(true) : null;
Textbox.state(playerName + " forfeited the battle!");
}
endBattleFlags = {
"outcome" : "opposing victory"
};
} else {
Textbos.state("Everyone forfeited the battel!");
endBattleFlags = {
"outcome" : "draw"
};
}
battleContext.endingFlags = endBattleFlags;
battleContext.finish();
battleContext.endDelay();
}
}
},
Expand Down Expand Up @@ -1857,6 +1916,9 @@ function BattleContext (client) {
actions.push("Run");
hotkeys[Settings._("keys => secondary")] = "Run";
}
if (battleContext.isCompetitiveBattle() && battleContext.delegates.Forfeit.shouldDisplayMenuOption(battleContext)) {
actions.push("Forfeit");
}
var moves = [];
foreach(currentBattler.usableMoves(), function (move) {
moves.push(move.move);
Expand Down Expand Up @@ -2209,24 +2271,28 @@ function BattleContext (client) {
if (major) {
chooseToSendOut(i);
} else {
battleContext.inputs.push({
action : "flee",
attempted : true
});
battleContext.flushInputs();
battleContext.escape(character.mostRecentlyFaintedPokemon);
battleContext.queue.push({
priority : 0,
action : function () {
if (!battleContext.finished) {
battleContext.fillEmptyPlaces(true, true);
if (response === "Run") {
battleContext.inputs.push({
action : "flee",
attempted : true
});
battleContext.flushInputs();
battleContext.escape(character.mostRecentlyFaintedPokemon);
battleContext.queue.push({
priority : 0,
action : function () {
if (!battleContext.finished) {
battleContext.fillEmptyPlaces(true, true);
}
}
}
});
battleContext.race(battleContext.queue);
battleContext.queue = [];
});
battleContext.race(battleContext.queue);
battleContext.queue = [];
} else {
battleContext.forfeitBattle();
}
}
}, battleContext.isWildBattle() && !alreadyAttemptedToEscape ? ["Run"] : [], null, null, null, null, true);
}, battleContext.isWildBattle() && !alreadyAttemptedToEscape ? ["Run"] : (battleContext.isCompetitiveBattle() ? ["Forfeit"] : []), null, null, null, null, true);
}
} else {
var sendOutRemainingPokemon = function () {
Expand Down Expand Up @@ -2659,6 +2725,13 @@ function BattleContext (client) {
}
}
},
forfeitBattle : function () {
battleContext.inputs.push({
action : "forfeit"
});
battleContext.flushInputs();
battleContext.waitForActions("command", () => Textbox.state(null));
},
attemptCapture : function (poke, ball, character) {
if (arguments.length < 3)
character = Game.player;
Expand Down Expand Up @@ -3222,6 +3295,9 @@ BattleContext.defaultDelegates = {
Run : {
shouldDisplayMenuOption : (battle) => true
},
Forfeit : {
shouldDisplayMenuOption : (battle) => true
},
Back : {
shouldDisplayMenuOption : (battle) => true
},
Expand Down
2 changes: 1 addition & 1 deletion battle/scripts/objects/unique/Relay.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Relay = {
break;
case "actions": // Actions from one of the parties has been received
Relay.processes[identifier].battle.receiveActions(data.filter(function (action) {
return action.trainer !== Relay.identification;
return action.trainer !== Relay.identification || action.action === "forfeit";
}));
break;
case "countdown":
Expand Down
3 changes: 3 additions & 0 deletions battle/scripts/objects/unique/TrialServer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
/*
An object used to test out multiplayer battles, locally
To use:
TrialServer.begin();
TrialServer.NPCBattle();
*/
TrialServer = {
begin : function () {
Expand Down

0 comments on commit 2282f38

Please sign in to comment.