Skip to content
Snippets Groups Projects
spniSelect.js 49.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • Joseph Kantel's avatar
    Joseph Kantel committed
        }
    
    
    
    /************************************************************
     * 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);
    }
    
    /************************************************************
     * This is the callback for the random buttons.
     ************************************************************/
    function updateRandomSelection (playerObject) {
        /* find a spot to store this player */
        for (var i = 0; i < players.length; i++) {
            if (!players[i]) {
                players[i] = playerObject;
    
                break;
            }
        }
    
    	updateSelectionVisuals();
    }
    
    /************************************************************
     * 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() {
        $searchModal.modal('show');
    }
    
    
    function closeSearchModal() {
    
        // 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);
    
    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
    
        if (field[0] === "-") {
    
            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;
        }
    }
    
    
    /** Event handler for the sort dropdown options. Fires when user clicks on a dropdown item. */
    $sortingOptionsItems.on("click", function(e) {
        sortingMode = $(this).find('a').html();
        $("#sort-dropdown-selection").html(sortingMode); // change the dropdown text to the selected option
    });
    
    /************************************************************
     * 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) {
    
        text = text || "&nbsp;";
    
        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 = Promise.resolve(fetchBehaviour(opp.folder));
    
                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);
    
    /**
     * Fetches the behaviour.xml file of the specified opponent directory.
     */
    function fetchBehaviour(path) {
    
        return $.ajax({
            type: "GET",
            url: path + "behaviour.xml",
            dataType: "text"
        });
    }
    
    
    /**
     * 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
    
    	var numTotalLines = 0;
    	var numUniqueDialogueLines = 0;
    	var numUniqueUsedPoses = 0;
        var lines = {};
        var poses = {};
    
        $(xml).find('state').each(function(idx, data) {
    
    		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;
    
            numUniqueLines : numUniqueDialogueLines,
    
            numPoses : numUniqueUsedPoses