Skip to content
Snippets Groups Projects
spniCore.js 42.5 KiB
Newer Older
  • Learn to ignore specific revisions
  • /************************************************************
     * The player clicked the player tags button. Shows the player tags modal.
     ************************************************************/
    function showPlayerTagsModal () {
        if (document.forms['player-tags'].elements.length <= 6) {
            /* maybe move this data to an external file if the hardcoded stuff changes often enough */
            var playerOptions = {
                'hair_length' : [
                    {value: 'bald', text: 'Bald - No Hair'},
                    {value: 'short_hair', text: 'Short Hair - Does Not Pass Jawline'},
                    {value: 'medium_hair', text: 'Medium Hair - Reaches Between Jawline and Shoulders'},
                    {value: 'long_hair', text: 'Long Hair - Reaches Beyond Shoulders'},
                    {value: 'very_long_hair long_hair', text: 'Very Long Hair - Reaches the Thighs or Beyond'}
                ],
                'physical_build' : [
                    {value: 'chubby'},
                    {value: 'athletic'},
                    {value: 'muscular athletic'}
                ],
                'height' : [
                    {value: 'tall'},
                    {value: 'average'},
                    {value: 'short'}
                ],
                'pubic_hair_style' : [
                    {value: 'shaved'},
                    {value: 'trimmed'},
                    {value: 'hairy'}
                ],
                'maleOnly_circumcision' : [
                    {value: 'circumcised'},
                    {value: 'uncircumcised'}
                ]
            }
    
            for (var choiceName in playerOptions) {
                var parsedName = choiceName.match(/^([^_]+)Only_(.*$)/) || [,'',choiceName];
                var choiceElem = '<label class="player-tag-select ' + parsedName[1] + '">Choose a' + ('aeiou'.includes(parsedName[2].charAt(0)) ? 'n ' : ' ');
                choiceElem += parsedName[2].replace(/_/g, ' ') + ':';
                choiceElem += '<select name="' + parsedName[2] + '"' + (parsedName[1] ? ' class="' + parsedName[1] + '"' : '') + '><option value=""></option>';
                playerOptions[choiceName].forEach(function(choice) {
                    var choiceText = choice.text || choice.value.charAt(0).toUpperCase() + choice.value.split(' ')[0].slice(1);
                    choiceElem += '<option value="' + choice.value + '">' + choiceText + '</option>';
                });
    
                choiceElem += '</select></label>';
                choiceElem = document.createRange().createContextualFragment(choiceElem);
                document.forms['player-tags'].appendChild(choiceElem);
            }
    
            // Safari doesn't support color inputs properly!
            var hairColorPicker = document.getElementById('hair_color_picker');
            var selectionType;
            try {
                selectionType = typeof hairColorPicker.selectionStart;
            } catch(e) {
                selectionType = null;
            }
    
            if (true || selectionType === 'number') {
    
                var hairColors = ['black_hair', 'white_hair', 'brunette', 'ginger', 'blonde',
                    'green_hair exotic_hair', 'blue_hair exotic_hair', 'purple_hair exotic_hair', 'pink_hair exotic_hair'];
                var eyeColors = ['dark_eyes', 'pale_eyes', 'red_eyes', 'amber_eyes', 'green_eyes', 'blue_eyes', 'violet_eyes'];
                var hairColorOptions = '';
                var eyeColorOptions = '';
                hairColors.forEach(function(tag) {
                    hairColorOptions += '<option value="' + tag + '">' + tag.split(' ')[0] + '</option>';
                });
                eyeColors.forEach(function(tag) {
                    eyeColorOptions += '<option value="' + tag + '">' + tag + '</option>';
                });
                $(hairColorPicker.parentNode).replaceWith('<select name="hair_color"><option value=""></option>' + hairColorOptions + '</select>');
                $(document.getElementById('eye_color_picker').parentNode).replaceWith('<select name="eye_color"><option value=""></option>' + eyeColorOptions + '</select>');
            }
    
            var rgb2hsv = function(rgb) {
              var r = parseInt(rgb.slice(1,3), 16)/255;
              var g = parseInt(rgb.slice(3,5), 16)/255;
              var b = parseInt(rgb.slice(5), 16)/255;
    
              var min = Math.min(r, Math.min(g,b));
              var max = Math.max(r, Math.max(g,b));
    
              if (max === 0) {
                return [0,0,0];
              }
    
              var maxOffset = max === r ? 0 : (max === g ? 2 : 4);
              var delta = max === r ? g-b : (max === g ? b-r : r-g);
    
              var h = 60 * (maxOffset + delta / (max - min));
              if (h < 0) {
                h += 360;
              }
    
              return [h, (max - min) / max * 100, max * 100];
            }
    
            /* convert the raw colors to corresponding tags and display next to selector */
            $('input[type=color]').on('input', function() {
                var h, s, v;
                [h,s,v] = rgb2hsv(this.value);
    
                var tag;
                color2tag:
                if (this.id === 'hair_color_picker') {
                  delete this.previousElementSibling.dataset.exotic;
                  if (v < 10) {
                    tag = 'black_hair';
                    break color2tag;
                  }
    
                  if (s < 25) {
                    if (v < 30) {
                      tag = 'black_hair';
                    } else {
                      tag = 'white_hair';
                    }
                    break color2tag;
                  }
    
                  if (s < 50 && h > 20 && h < 50) {
                    tag = 'brunette';
                    break color2tag;
                  }
    
                  if (h < 50) {
                    tag = 'ginger';
                  } else if (h < 65) {
                    tag = 'blonde';
                  } else if (h < 325) {
                    this.previousElementSibling.dataset.exotic = 'exotic_hair';
                    if (h < 145) {
                      tag = 'green_hair';
                    } else if (h < 255) {
                      tag = 'blue_hair';
                    } else if (h < 290) {
                      tag = 'purple_hair';
                    } else {
                      tag = 'pink_hair';
                    }
                  } else {
                    tag = 'ginger';
                  }
                } else if (this.id === 'eye_color_picker') {
    
                  if (v < 25) {
                    tag = 'dark_eyes';
                    break color2tag;
                  }
    
                  if (s < 20) {
                    tag = 'pale_eyes';
                    break color2tag;
                  }
    
                  if (h < 15) {
                    tag = 'red_eyes';
                  } else if (h < 65) {
                    tag = 'amber_eyes';
                  } else if (h < 145) {
                    tag = 'green_eyes';
                  } else if (h < 255) {
                    tag = 'blue_eyes';
                  } else if (h < 325) {
                    tag = 'violet_eyes';
                  } else {
                    tag = 'red_eyes';
                  }
                }
    
                this.previousElementSibling.value = tag || '';
            });
    
            $('input[name=skin_color_picker]').on('input', function() {
                if (this.value < 25) {
    
                    tag = 'pale-skinned';
    
                } else if (this.value < 50) {
    
                    tag = 'fair-skinned';
    
                } else if (this.value < 75) {
    
                    tag = 'olive-skinned';
    
                    tag = 'dark-skinned';
    
                }
    
                this.previousElementSibling.value = tag || '';
            });
    
            $('.modal-button.clearSelections').click(function() {
                var formElements = document.forms['player-tags'].elements;
                for (var i = 0; i < formElements.length; i++) {
                    if (formElements[i].type !== 'color') {
                        formElements[i].value = '';
                    }
                }
            });
        }
    
        $playerTagsModal.modal('show');
    }
    
    
    /************************************************************
     * The player clicked on a table opacity button.
     ************************************************************/
    function toggleTableVisibility () {
    	if (tableOpacity > 0) {
    		$gameTable.fadeOut();
    		tableOpacity = 0;
    	} else {
    		$gameTable.fadeIn();
    		tableOpacity = 1;
    	}
    }
    
    function forceTableVisibility(state) {
        if (!state) {
    		$gameTable.fadeOut();
    		tableOpacity = 0;
    	} else {
    		$gameTable.fadeIn();
    		tableOpacity = 1;
    	}
    }
    
    /**********************************************************************
     *****                     Utility Functions                      *****
     **********************************************************************/
    
    /************************************************************
     * Returns a random number in a range.
     ************************************************************/
    function getRandomNumber (min, max) {
    	return Math.floor(Math.random() * (max - min) + min);
    }
    
    
    /************************************************************
     * Changes the first letter in a string to upper case.
     ************************************************************/
    String.prototype.initCap = function() {
    	return this.substr(0, 1).toUpperCase() + this.substr(1);
    }
    
    /************************************************************
    
     * Counts the number of elements that evaluate as true, or,
    
     * if a function is provided, passes the test implemented by it.
     ************************************************************/
    Array.prototype.countTrue = function(func) {
        var count = 0;
        for (var i = 0; i < this.length; i++) {
            if (i in this
                && (func ? func(this[i], i, this) : this[i])) {
                count++;
            }
        }
        return count;
    }
    
    
    /************************************************************
     * Generate a random alphanumeric ID.
     ************************************************************/
    function generateRandomID() {
        var ret = ''
        for (let i=0;i<10;i++) {
            ret += 'abcdefghijklmnopqrstuvwxyz1234567890'[getRandomNumber(0,36)]
        }
    
    /**********************************************************************
     * Returns the width of the visible screen in pixels.
     **/
    
    FarawayVision's avatar
    FarawayVision committed
    function getScreenWidth ()
    
    {
    	/* fetch all game screens */
    	var screens = document.getElementsByClassName('screen');
    
    	/* figure out which screen is visible */
    
    FarawayVision's avatar
    FarawayVision committed
    	for (var i = 0; i < screens.length; i++)
    
    FarawayVision's avatar
    FarawayVision committed
    		if (screens[i].offsetWidth > 0)
    
            {
    			/* this screen is currently visible */
    			return screens[i].offsetWidth;
    		}
    	}
    }
    
    /**********************************************************************
     * Automatically adjusts the size of all font based on screen width.
     **/
    
    FarawayVision's avatar
    FarawayVision committed
    function autoResizeFont ()
    
    {
    	/* resize font */
    	var screenWidth = getScreenWidth();
    	document.body.style.fontSize = (14*(screenWidth/1000))+'px';
    
    
    	if (backgroundImage && backgroundImage.height && backgroundImage.width) {
    		var w = window.innerWidth, h = window.innerHeight;
    		if (h > (3/4) * w) {
    			h = (3/4) * w;
    		} else {
    
    			w = 4 * h / 3;
    
    		var ar = backgroundImage.width / backgroundImage.height;
    		if (ar > 4/3) {
    			var scale = Math.sqrt(16/9 / ar);
    			$("body").css("background-size", "auto " + Math.round(scale * h) + "px");
    
    			var scale = Math.sqrt(ar);
    			$("body").css("background-size", Math.round(scale * w) + "px auto");
    
    	/* set up future resizing */
    	window.onresize = autoResizeFont;
    
    
    /* Get the number of players loaded, including the human player.*/
    function countLoadedOpponents() {
        return players.reduce(function (a, v) { return a + (v ? 1 : 0); }, 0);
    }