"game/git@ssh.gitgud.io:Averall/degrees-of-lewdity-plus.git" did not exist on "10c8becccd6df30599f1f52635615a17d77af554"
Newer
Older
************************************************************/
function backToSelect () {
/* switch screens */
screenTransition($individualSelectScreen, $selectScreen);
screenTransition($groupSelectScreen, $selectScreen);
}
/************************************************************
* The player clicked on the start game button on the main
* select screen.
************************************************************/
function advanceSelectScreen () {

FarawayVision
committed
console.log("Starting game...");
gameID = generateRandomID();
'date': (new Date()).toISOString(),
'userAgent': navigator.userAgent,
'origin': getReportedOrigin(),
'table': {},
'tags': players[HUMAN_PLAYER].tags
for (let i=1;i<5;i++) {
if (players[i]) {
usage_tracking_report.table[i] = players[i].id;
$.ajax({
url: USAGE_TRACKING_ENDPOINT,
method: 'POST',
data: JSON.stringify(usage_tracking_report),
contentType: 'application/json',
error: function (jqXHR, status, err) {
console.error("Could not send usage tracking report - error "+status+": "+err);
},
});
}
players.forEach(function(player) {
player.preloadStageImages(0);
});
transcriptHistory = [];
advanceToNextScreen($selectScreen);
}
/************************************************************
* The player clicked on the back button on the main select
* screen.
************************************************************/
function backSelectScreen () {
screenTransition($selectScreen, $titleScreen);
}
/* The player selected an alternate costume for an opponent.
* `slot` is the 1-based opponent slot affected.
* `inGroup` is true if the affected opponent is on the group selection screen.
*/
function altCostumeSelected(slot, inGroup) {
var costumeSelector = (inGroup ? $groupCostumeSelectors[slot-1] : $individualCostumeSelectors[slot-1]);
var selectImage = (inGroup ? $groupImages[slot-1] : $individualImages[slot-1]);
var opponent = (inGroup ? selectableGroups[groupSelectScreen][groupPage[groupSelectScreen]].opponents[slot-1] : shownIndividuals[slot-1]);
var selectedCostume = costumeSelector.val();
var costumeDesc = undefined;
if (selectedCostume.length > 0) {
for (let i=0;i<opponent.alternate_costumes.length;i++) {

FarawayVision
committed
if (opponent.alternate_costumes[i].folder === selectedCostume) {
costumeDesc = opponent.alternate_costumes[i];
break;
}
}
}
opponent.selectAlternateCostume(costumeDesc);
selectImage.attr('src', opponent.selection_image);
/**********************************************************************
***** Display Functions *****
**********************************************************************/
/************************************************************
* Displays all of the current players on the main select
* screen.
************************************************************/
function updateSelectionVisuals () {
/* update all opponents */
for (var i = 1; i < players.length; i++) {

ReformCopyright
committed
/* Check to see if all opponents are loaded. */

ReformCopyright
committed
var filled = 0, loaded = 0;
players.forEach(function(p, idx) {
if (idx > 0) {
filled++;
loaded++;
}

ReformCopyright
committed
});

ReformCopyright
committed
/* if enough opponents are selected, and all those are loaded, then enable progression */
$selectMainButton.attr('disabled', filled < 2 || loaded < filled);

ReformCopyright
committed
/* if all slots are taken, disable fill buttons */
$selectRandomButtons.attr('disabled', filled >= 4);

ReformCopyright
committed
$selectRemoveAllButton.attr('disabled', filled <= 0 || loaded < filled);
/* Disable buttons while loading is going on */
$selectRandomTableButton.attr('disabled', loaded < filled);
$groupButton.attr('disabled', loaded < filled);
/* Update suggestions images. */
var current_player_count = countLoadedOpponents();
if (current_player_count >= 3) {

FarawayVision
committed
var suggested_opponents = loadedOpponents.filter(function(opp) {
/* hide selected opponents */
if (players.some(function(p) { return p && p.id == opp.id; })) {
return false;
}

FarawayVision
committed
return true;
});

FarawayVision
committed
/* sort opponents */
suggested_opponents.sort(sortOpponentsByMostTargeted());
var suggestion_idx = 0;
for (var i=1;i<players.length;i++) {

FarawayVision
committed
if (players[i] === undefined) {
updateSuggestions(i-1, suggested_opponents, suggestion_idx);
$selectSuggestions[i-1].show();
suggestion_idx += 4;
} else {
$selectSuggestions[i-1].hide();
}
}
} else {
for (var i=0;i<4;i++) {
$selectSuggestions[i].hide();
}
}
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
/************************************************************
* This is the callback for the group clicked rows, it
* updates information on the group screen.
************************************************************/
function updateGroupScreen (playerObject) {
/* find a spot to store this player */
for (var i = 0; i < storedGroup.length; i++) {
if (!storedGroup[i]) {
storedGroup[i] = playerObject;
$groupLabels[i+1].html(playerObject.label);
break;
}
}
/* enable the button */
$groupButton.attr('disabled', false);
}
/************************************************************
* Hides the table on the single selection screen.
************************************************************/
function hideSelectionTable() {
mainSelectHidden = !mainSelectHidden;
if (mainSelectHidden) {
$selectTable.hide();
}
else {
$selectTable.show();
}
}
/************************************************************
* Hides the table on the single selection screen.
************************************************************/
function hideSingleSelectionTable() {
singleSelectHidden = !singleSelectHidden;
if (singleSelectHidden) {
$individualSelectTable.hide();
}
else {
$individualSelectTable.show();
}
}
/************************************************************
* Hides the table on the single group screen.
************************************************************/
function hideGroupSelectionTable() {
groupSelectHidden = !groupSelectHidden;
if (groupSelectHidden) {
$groupSelectTable.hide();
}
else {
$groupSelectTable.show();
}
}
function openSearchModal() {

ReformCopyright
committed
$searchModal.modal('show');
}
function closeSearchModal() {
Chase Southwood
committed
// perform the search and sort logic
updateSelectableOpponents();
// update
updateIndividualSelectScreen();
updateIndividualCountStats();
function clearSearch() {
$searchName.val(null);
$searchTag.val(null);
$searchSource.val(null);
closeSearchModal();
}
function changeSearchGender(gender) {
chosenGender = gender;
setActiveOption($searchGenderOptions, gender);
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
function openGroupSearchModal() {
$groupSearchModal.modal('show');
}
function closeGroupSearchModal() {
// perform the search and sort logic
updateSelectableGroups(groupSelectScreen);
// update
updateGroupSelectScreen();
updateGroupCountStats();
}
function clearGroupSearch() {
$groupSearchName.val(null);
$groupSearchGroupName.val(null);
$groupSearchTag.val(null);
$groupSearchSource.val(null);
closeGroupSearchModal();
}
function changeGroupSearchGender(gender) {
chosenGroupGender = gender;
setActiveOption($groupSearchGenderOptions, gender);
}
/************************************************************
* Sorting Functions
************************************************************/
* Callback for Arrays.sort to sort an array of objects by the given field.
* Prefixing "-" to a field will cause the sort to be done in reverse.
* Examples:
* // sorts myArr by each element's first name (A-Z)
* myArr.sort(sortOpponentsByField("first"));
* // sorts myArr by each element's last name (Z-A)
* myArr.sort(sortOpponentsByField("-last"));
*/
function sortOpponentsByField(field) {
// check for prefix
var order = 1; // 1 = forward, -1 = reversed
order = -1;
field = field.substr(1);
}
return function(opp1, opp2) {
var compare = 0;
if (opp1[field] < opp2[field]) {
compare = -1;
}
else if (opp1[field] > opp2[field]) {
compare = 1;
}
return order * compare;
}
}
/**
* Callback for Arrays.sort to sort an array of objects over multiple given fields.
* Prefixing "-" to a field will cause the sort to be done in reverse.
* This should allow more flexibility in the sorting order.
* Example:
* // sorts myArr by each element's number of layers (low to high),
* // and for elements whose layers are equivalent, sort them by first name (Z-A)
* myArr.sort(sortOpponentsByMultipleFields("layers", "-first"));
*/
function sortOpponentsByMultipleFields() {
var fields = arguments; // retrieve the args passed in
return function(opp1, opp2) {
var i = 0;
var compare = 0;
// if both elements have the same field, check the next ones
while (compare === 0 && i < fields.length) {
compare = sortOpponentsByField(fields[i])(opp1, opp2);
i++;
}
return compare;
}
}
ReformCopyright
committed
/**
* Special Callback for Arrays.sort to sort an array of opponents on
* the total number of lines targeting them the currently selected
* opponents have.
*/
function sortOpponentsByMostTargeted() {
return function(opp1, opp2) {
counts = [opp1, opp2].map(function(opp) {
return players.reduce(function(sum, p) {
if (p && p.targetedLines && opp.id in p.targetedLines) {
ReformCopyright
committed
sum += p.targetedLines[opp.id].count;
}
return sum;
}, 0);
});
if (counts[0] > counts[1]) return -1;
if (counts[0] < counts[1]) return 1;
return 0;
}
}
function setSortingMode(mode) {
sortingMode = mode;
$("#sort-dropdown-selection").html(sortingMode); // change the dropdown text to the selected option
individualPage = 0; // reset the page number
}
/** Event handler for the sort dropdown options. Fires when user clicks on a dropdown item. */
$sortingOptionsItems.on("click", function(e) {
setSortingMode($(this).find('a').html());
/************************************************************
* Word wrapping Functions
************************************************************/
/**
* Inserts a fixed-size HTML element with the specified text to allow the content
* to be either word-wrapped (if the text is long and spaces are present)
* or word-broken (if text is long and no spaces are present).
*/
function wordWrapHtml(text) {
return "<table class=\"wrap-text\"><tr><td>" + text + "</td></tr></table>";
/************************************************************
* Dynamic dialogue and image counting functions
************************************************************/
/** Event handler for the individual selection screen credits button. */
$individualCreditsButton.on('click', function(e) {
updateIndividualCountStats()
/** Event handler for the group selection screen credits button. */
$groupCreditsButton.on('click', function(e) {
updateGroupCountStats();
* Loads and displays the number of unique dialogue lines and the number of pose images
* into the character's player object for those currently on the selection screen.
* Only loads if the unique line count or image count is not known.
*/
function updateOpponentCountStats(opponentArr, uiElements) {
opponentArr.forEach(function(opp, idx) {
// load behaviour file if line/image count is not known
if (opp && (opp.uniqueLineCount === undefined || opp.posesImageCount === undefined)) {
uiElements.countBoxes[idx].css("visibility", "visible");
// retrieve line and image counts
if (DEBUG) {
console.log("[LineImageCount] Fetching counts for " + opp.label + " in slot " + idx);
var countsPromise = new Promise(function (resolve, reject) {
fetchCompressedURL(
opp.folder + 'behaviour.xml',
resolve, reject
);
});
countsPromise.then(countLinesImages).then(function(response) {
opp.uniqueLineCount = response.numUniqueLines;
opp.posesImageCount = response.numPoses;
// show line and image counts
if (DEBUG) {
console.log("[LineImageCount] Loaded " + opp.label + " from behaviour: " +
opp.uniqueLineCount + " lines, " + opp.posesImageCount + " images");
uiElements.lineLabels[idx].html(opp.uniqueLineCount);
uiElements.poseLabels[idx].html(opp.posesImageCount);
// this character's counts were previously loaded
if (DEBUG) {
console.log("[LineImageCount] Loaded previous count for " + opp.label + ": " +
opp.uniqueLineCount + " lines, " + opp.posesImageCount + " images)");
uiElements.countBoxes[idx].css("visibility", "visible");
uiElements.lineLabels[idx].html(opp.uniqueLineCount);
uiElements.poseLabels[idx].html(opp.posesImageCount);
// there is no character in the slot
uiElements.countBoxes[idx].css("visibility", "hidden");
uiElements.lineLabels[idx].html("");
uiElements.poseLabels[idx].html("");
/** Dialogue/image count update function for the individual selection screen. */
function updateIndividualCountStats() {
if (individualCreditsShown) {
var individualUIElements = {
countBoxes : $individualCountBoxes,
lineLabels : $individualLineCountLabels,
poseLabels : $individualPoseCountLabels
};
updateOpponentCountStats(shownIndividuals, individualUIElements);
}
}
/** Dialogue/image count update function for the group selection screen. */
function updateGroupCountStats() {
if (groupCreditsShown) {
var groupUIElements = {
countBoxes : $groupCountBoxes,
lineLabels : $groupLineCountLabels,
poseLabels : $groupPoseCountLabels
};
updateOpponentCountStats(shownGroup, groupUIElements);
/**
* Callback to parse the number of lines of dialogue and number of images
* given a character's behaviour XML. Returns the counts as an object with
* properties numTotalLines, numUniqueLines, and numPoses.
*/
function countLinesImages(xml) {
// parse all lines of dialogue and all images

ReformCopyright
committed
var numTotalLines = 0;
var numUniqueDialogueLines = 0;
var numUniqueUsedPoses = 0;
var lines = {};
var poses = {};
$(xml).find('state').each(function(idx, data) {

ReformCopyright
committed
numTotalLines++;
// count only unique lines of dialogue
if (lines[data.textContent.trim()] === undefined) numUniqueDialogueLines++;
lines[data.textContent.trim()] = 1;
// count unique number of poses used in dialogue
// note that this number may differ from actual image count if some images
// are never used, or if images that don't exist are used in the dialogue
if (poses[data.getAttribute("img")] === undefined) numUniqueUsedPoses++;
poses[data.getAttribute("img")] = 1;

ReformCopyright
committed
numTotalLines : numTotalLines,
numUniqueLines : numUniqueDialogueLines,
numPoses : numUniqueUsedPoses