GIF89a; %PDF-1.5 %���� ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY
Server IP : 134.29.175.74 / Your IP : 216.73.216.160 Web Server : nginx/1.10.2 System : Windows NT CST-WEBSERVER 10.0 build 19045 (Windows 10) i586 User : Administrator ( 0) PHP Version : 7.1.0 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/nginx/html/download/ |
Upload File : |
// js/site.js // _Initialize_Accesskey(by) ............. Initialize the accesskeys on the page. // _Initialize_Site() .................... Add submit eventListener for LoadingPleaseWait to all forms. // AccesskeysCreate() .................... Create accesskeys. // AccesskeysDisable() ................... Disable accesskeys. // AccesskeysKeyDown(evt) ................ Handle keyup events. // console.stub .......................... Avoid `console` errors in browsers that lack a console. // BackspaceTrap() ....................... To possibly override backspace keypress. // ClearSelectedText() ................... Clear any text selection // ColorSelect(e) ........................ Color the select options. // ColorSelectAttach() ................... Add 'change' EventListener 'ColorSelect(this);' to all select elements. // ElementBounds(eId) .................... Return left, top, right, bottom, width, height, border, margin, and padding of an element. // elementLeftTop(e) ..................... Returns left and top of an element. // errordialog(msg, url, linenumber) ..... Display javascript errors at the top of the browser window. // eventHide(UTRu) ....................... Hide this event content. // eventHideAll(userId, turn) ............ Hide all event content for this turn. // eventShow(UTRu) ....................... Show this event content. // eventShowAll(userId, turn) ............ Show all event content for this turn. // eventTurnHide(userId, turn) ........... Hide all turn Events. // eventTurnShow(userId,turn) ............ Show turn Events based on their current status. // EPPZScrollTo.scrollVerticalToElementById(id, pad) // Scroll to element with animation (slow) // formSubmit(e, formTask, formAction) ... Submit the form while disabling the button. // getE(id,p,t,by) ....................... Set e and eId global values. // formSubmit_GetForm(e) ................. Return the form elemnt. // GetMouse_mxmy(evt) .................... Set mx and my to the mouse position. // getValue(id, p, t, by) ................ Set e and eId values and return e.value with cleanup. // Help(helpTip) ......................... Control help button onClick, onMouseDown, onMouseOut, and onMouseOver. // HelpDisplay(helpName) ................. Display help. // HelpNotFound() ........................ Show help not written if empty or 404 error. // htmlSafe(str) ......................... Return an HTML safe string. // IncrementCounter(thisFunction) ........ Increment the function counter. // IsNumeric(n) .......................... Returns true if n is numeric, else false. // LoadingPleaseWait() ................... Show Loading... and hide pageContent when a form is submitted. // moveDisplay(menuType, mXY) ............ Display the mXY menu. // menuDrag() ............................ Allows player to drag the MapMenu to another location. // menuHide(by) .......................... Hide the XY menu. // Refresh_LastAccessOnce(sound) ......... Refresh the playergame lastAccess time and play sound. // Refresh_LastAccessAuto(sound, by) ..... Refresh the playergame lastAccess time and play sound automatically every SoundTimer seconds. // ScreenExit(e, action, name) ........... Exit play and submit form (Also set name or 'task' value). // SeeHide_Events(see_hide) .............. Show or hide Events. // SeeHide_Fleets(see_hide) .............. Show or hide fleets and ships. // SeeHide_Map(see_hide) ................. Show or hide map. // SeeHide_Settings(see_hide) ............ Show or hide game settings. // SeeHide_Score(see_hide) ............... Show or hide score. // SeeHide_Techs(see_hide) ............... Show or hide techs. // SetGameSetting(e) ..................... Set database, $_SESSION, and javascript values. // SoundManage(e) ........................ Manage sound settings. // SoundPlay(soundfile, by) .............. Play the soundfile. // SoundPlayByName(sound, by) ............ Play the sound by name. // SoundPlayByNameAuto(sound, by) ........ Play sound by name automatically every SoundTimer seconds. // SoundPlayByNameAutoReturn() ........... Callback to re-call SoundPlayByNameAuto(). // SoundReset() .......................... Reset javascript sound setting to default values. // SoundSave() ........................... Save sound setting. // SoundSet(e) ........................... Change a sound setting. // starNoteDisplay(XY) ................... Rate or make notes on star. // StarNoteSave(e) ....................... Rate or make notes on star. // starValue() ........................... Calculate and return the value of all planets at a star. // ttDisplay(evt) ........................ Display map tooltip. // ttDisplay_Events() .................... Display game Events at XY. // ttDisplay_Fleets() .................... Display hex location. // ttDisplay_InSpace() ................... Display ships at XY. // ttDisplay_Location() .................. Display star name and hex location if at a star. // ttDisplay_Notes() ..................... Display Notes about XY. // ttDisplay_Planets() ................... Display known planets at XY. // ttDisplay_Planets_Contents(pn,uId) .... Return planet contents. This function is only called by ttDisplay_Planets(). // ttDisplay_Production() ................ Display units produced at XY ( in space and on planets ). // ttDisplay_onClick() ................... Display the onClick task. // ttDisplay_TKO(TKO_XY) ................. Display warning if TKO needs cover here. // ttEnemyHasSpaceCombatUnits(eId, XY) ... Returns true if the enemy has space combat units (warships or orbital bases). // ttLostContact(pp) ..................... Return true if the player has 'Lost Contact' with this planet in the past, else false. // ttPd(pn) .............................. Return planet description for console DEBUGging. // ttPlanetIsOriginal() .................. Returns true if the planet has original TYPE HAB NM, else false. // ttPlanetIsPlayer() .................... Returns true if the planet TYPE HAB NM has not been changee by production, else false. // ttTR(turn) ............................ Returns TR. // Sound is played by: PHP: audioPlay() and refreshLastAccessSound() // Javascript: by Refresh_LastAccessOnce(), Refresh_LastAccessAuto(), SoundPlay(), SoundPlayByName(), SoundPlayByNameAuto(), and SoundPlayByNameAutoReturn(). // BEGIN variable settings. // Use DEBUG = DEBUG_OFF; to stop debugging. // Use DEBUG = DEBUG_ON; to start debugging. // DEBUG_ON is defined by pageFooter_site_js.phpinc as the value of $debuggingAvailable which is set in application.phpinc line 22. // If $debuggingAvailable is false then DEBUG_ON will also be false as debugging is not available. let DEBUG_OFF = false; let DEBUG_doc_on = false; // DEBUG set of document onclick, onmousedown, onmousemove, onmouseout, onmouseover, onmouseup, and onselectstart. let DEBUG_SeeEventsFleetsTechs = false; let DOC = {}; DOC.onclick = null; // Remember document.onclick function name. DOC.onmousedown = null; // Remember document.onmousedown function name. DOC.onmousemove = null; // Remember document.onmousemove function name. DOC.onmouseout = null; // Remember document.onmouseout function name. DOC.onmouseover = null; // Remember document.onmouseover function name. DOC.onmouseup = null; // Remember document.onmouseup function name. DOC.onselectstart = null; // Remember document.onselectstart function name. let Accesskeys = {}; let evt; // The current event. let form; // Form object. let movesToTextTimer = false; let mx; // mouse x pixel position. let my; // mouse y pixel position. let Save_mxmy = {}; // Array to save previous mx, my.; //let SeeHide_EventsLoaded = false; //let SeeHide_PlanetsLoaded = false; let SeeHide_ScoreLoaded = false; let SeeHide_SettingsLoaded = false; let SoundLastPlayedSound = ''; // The name of the last sound played. let SoundLastPlayedTime = 0; // The getTime() a sound was last played. let SoundPlayByNameAutoBy; // Save SoundPlayByNameAuto() by for use by SoundPlayByNameAuto(); let SoundPlayByNameAutoRefresh; // Save SoundPlayByNameAuto() refresh for use by SoundPlayByNameAuto(); let SoundPlayByNameAutoSetTimeout; // The setTimeout call for use by SoundPlayByNameAuto() to call clearTimeout(SoundPlayByNameAutoSetTimeout) and stop auto calls. let SoundPlayByNameAutoSound; // Save SoundPlayByNameAuto() sound for use by SoundPlayByNameAuto(); let ttContent_Planets; // Store tooltip planet text. let SoundPlayByNameAutoReturnCount = 0; // Count SoundPlayByNameAutoReturn() calls. // END variable settings. // _DEBUG_loaded_or_off() // Returns true if DEBUG_ON is defined and (DEBUG_ON is false or DEBUG_ON is true and debugging is initalized). function _DEBUG_loaded_or_off() { return ( typeof DEBUG_ON !== 'undefined' ) && ( !DEBUG_ON || ( DEBUG_ON && _Initialize_debug.initalized ) ); } // END _DEBUG_loaded_or_off. // _Initialize(initFunction) // Call all the InitializeFunctions that were defined. // InitializeFunctions is a comma seperated list of function names. // InitializeFunctions is defined in the js/site_js.phpinc file from the php $GLOBALS['_PAGE']['onload'] variable. // $GLOBALS['_PAGE']['onload'] is defined in the common/pageHeader.phpinc file. // First preset site function are added. Then functions listed in the php pageHeader[] function. function _Initialize(initFunction='') { let DEBUG = true; // Cannot trust that DEBUG_ON is defined at this point. if ( !DEBUG ) { console.log(`${PC}_Initialize[${initFunction}]`,CH); } //if ( document.getElementById('pageHeader') ) { document.getElementById('pageHeader').style.display = 'block'; } if ( initFunction === '' ) { // Was _Initialize called without a function name? // Yes, call _Initialize[] for each of the InitializeFunctions. if ( DEBUG ) { console.group(`${PC}_Initialize[]${PC} InitializeFunctions=${InitializeFunctions}`,CG,CL); }//Collapsed _Initialize_Page(); InitializeFunctions.forEach((InitializeFunction, index) => { // Loop thru the InitializeFunctions. if ( DEBUG ) { console.log(`${PC}_Initialize+'[${InitializeFunction}]'`,CC); } _Initialize(InitializeFunction); // Call _Initialize with the function name. }); // Loop thru the InitializeFunctions. } else { // Was _Initialize called without a function name? // No, Check if the initFunction exists. if ( DEBUG ) { console.group(`${PC}_Initialize[${initFunction}]`,CG); }//Collapsed if ( window[initFunction] ) { // Does the initFunction function exist? // Yes, Call the specified initFunction. if ( DEBUG ) { console.log(PC+initFunction+'[]',CC); } window[initFunction](); // Run the initFunction function. } else { // Does the function exist? // No, Try again in 1 second. Attempts are limited to 5 tries. if ( DEBUG ) { console.log(`${PC}_Initialize.initFunction=${_Initialize.initFunction}`,CI); } _Initialize.initFunction++; if ( isNaN(_Initialize.initFunction) ) { _Initialize.initFunction = 1; if ( DEBUG ) { console.log(`${PC}_Initialize.initFunction=${_Initialize.initFunction}`,CI); } } console.log(`${PC}${initFunction} is not defined. _Initialize.initFunction=${_Initialize.initFunction}`,CF); if ( _Initialize.initFunction < 5 ) { setTimeout(function(){ _Initialize(initFunction); },1000); // Try again in 1 second. } } // Does the function exist? } // Was _Initialize called without a function name? if ( DEBUG ) { console.groupEnd(); } } // END _Initialize. // _Initialize_Accesskey(by) // Initialize the accesskeys on the page. function _Initialize_Accesskey(by) { IncrementCounter(_Initialize_Accesskey); let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.groupCollapsed(PC+'_Initialize_Accesskey['+_Initialize_Accesskey.counter+'] by='+by,CG); } else { console.log(PC+'_Initialize_Accesskey['+_Initialize_Accesskey.counter+'] by='+by,CH); } // Add keydown and keyup listeners. document.addEventListener('keydown',AccesskeysKeyDown); document.addEventListener('keyup',AccesskeysKeyDown); //document.keydown = AccesskeysKeyDown; //document.keyup = AccesskeysKeyDown; // Capture when the mouse leaves the body. This is needed because keydown can no longer trap the esc key until the body is clicked. // This would not need to be done if there was no event listener for document.onclick. let Body = document.getElementsByTagName('body'); //console.log('Body'+Body); Body[0].addEventListener("mouseleave",function() { AccesskeySpecialFunction = {}; },0); // Remove 'or hit esc' if the mouse leaves the body. if ( DEBUG ) { console.log(PC+'AccesskeysCreate[]',CC); } AccesskeysCreate('_Initialize_Accesskey 126'); if ( DEBUG ) { console.groupEnd(); } } // END _Initialize_Accesskey. // _Initialize_Page(by) // Initialize the accesskeys on the page. function _Initialize_Page() { let DEBUG = DEBUG_ON; if ( DEBUG ) { console.groupCollapsed(PC+'_Initialize_Page[]',CG); } else { console.log(PC+'_Initialize_Page[]',CH); } if ( document.getElementById('pageContent') ) { if ( DEBUG ) { console.log(PC+'Display pageContent.',CL); } document.getElementById('pageContent').style.display = 'block'; } if ( document.getElementById('pageFooter') ) { if ( DEBUG ) { console.log(PC+'Display pageFooter.',CL); } document.getElementById('pageFooter').style.display = 'block'; if ( document.getElementById('showfonts') ) { if ( DEBUG ) { console.log('window.location.href.indexOf("admin")='+window.location.href.indexOf("admin")); } if( window.location.href.indexOf("admin") === -1 ) { if ( DEBUG ) { console.log(PC+'Hide showfonts.',CL); } document.getElementById('showfonts').style.visibility = 'hidden'; } else { if ( DEBUG ) { console.log(PC+'Leave showfonts displayed.',CL); } } } } if ( DEBUG ) { console.groupEnd(); } } // END _Initialize_Page. // _Initialize_Site() // Add submit eventListener for LoadingPleaseWait to all forms. let _Initialize_Site_Done = false; function _Initialize_Site() { IncrementCounter(_Initialize_Site); let DEBUG = false; // Cannot trust that DEBUG_ON is defined at this point. if ( DEBUG ) { console.groupCollapsed(PC+'_Initialize_Site['+_Initialize_Site.counter+'] site.js',CG); } else { console.log(PC+'_Initialize_Site['+_Initialize_Site.counter+'] site.js',CH); }// // Wait for the pageFooter element, the UseCanvasMap js variable, and either DEBUG_ON is off or the _Initialize_debug.initalized variable is set. let error = false; //if ( !document.getElementById('pageFooter') ) { error = 'The pageFooter has not loaded'; } //if ( !error && typeof UseCanvasMap === 'undefined' ) { error = 'The canvas is not ready'; } //if ( !error && typeof _Initialize_debug.initalized === 'undefined' ) { error = 'DEBUG is not ready'; } if ( !error ) { // Add LoadingPleaseWait event listener to all form submit actions. for ( let i=0; i<document.forms.length; i++ ) { document.forms[i].addEventListener('submit',LoadingPleaseWait); } if ( DEBUG ) { console.log(PC+'_Initialize_Accesskey[]',CC); } _Initialize_Accesskey('_Initialize_Site 121'); // Get accesskey items. if ( DEBUG && !UseCanvasMap ) { console.log(PC+'Not using canvas map. UseCanvasMap='+UseCanvasMap,CI); } _Initialize_Site_Done = true; } else { if ( _Initialize_Site.counter < 10 ) { if ( DEBUG ) { console.log(PC+'setTimeout[_Initialize_Site,100] '+error,CC); } setTimeout(_Initialize_Site,100); } } /** / // No longer using roboto fonts. Switched to Arial on 2021.01.04. if ( DEBUG ) { console.log(`${PC}document.fonts.onloadingdone function set.`,CD); } /** / document.fonts.onloadingdone = function (fontFaceSetEvent) { console.log(`${PC}document.fonts.onloadingdone == ${fontFaceSetEvent.fontfaces.length} font faces loaded.`,CA); //console.log(`${PC}robotothin=${document.fonts.check('1em robotothin')}`,CB); //console.log(`${PC}robotolight=${document.fonts.check('1em robotolight')}`,CB); console.log(`${PC}robotoregular=${document.fonts.check('1em robotoregular')}`,CB); console.log(`${PC}robotomedium=${document.fonts.check('1em robotomedium')}`,CB); console.log(`${PC}robotobold=${document.fonts.check('1em robotobold')}`,CB); console.log(`${PC}robotoblack=${document.fonts.check('1em robotoblack')}`,CB); if ( document.fonts.check('1em robotoregular') ) { document.body.style.fontFamily = "robotoregular, Helvetica, Verdana, Geneva, Arial, sans-serif"; } //_Initialize_Canvas(); //document.body.style.fontFamily = "robotoregular, Arial, sans-serif";//'Helvetica', 'Verdana', 'Geneva', 'Arial', sans-serif; /** / }; /**/ if ( DEBUG ) { console.groupEnd(); } } // END _Initialize_Site. // AccesskeySpecial(27,keyFunction) // Set AccesskeySpecialFunction to trap keypress. let AccesskeySpecialFunction = {}; function AccesskeySpecial(keyCode=false,keyFunction='') { if ( keyCode !== false ) { if ( keyFunction !== '') { AccesskeySpecialFunction[keyCode] = keyFunction; } else { delete AccesskeySpecialFunction[keyCode]; } } } // END AccesskeySpecial. // AccesskeysCreate(by) // Create accesskeys. function AccesskeysCreate(by) { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.groupCollapsed(`${PC}AccesskeysCreate[] by=${by}`,CG); } else { //console.log(`${PC}AccesskeysCreate[] by=${by}`,CH); } Accesskeys = {}; let AccesskeyElements = document.getElementsByClassName('accesskey'); if ( DEBUG ) { console.log(PC+'AccesskeyElements.length='+AccesskeyElements.length,CL); } let AccesskeyElement; let AccesskeyFound; let ClassNames; for ( i=0; i<AccesskeyElements.length; i++ ) { // Loop thru Accesskeys. AccesskeyElement = AccesskeyElements[i]; //console.log(AccesskeyElement.nodeName+' '+AccesskeyElement.type+' '+AccesskeyElement.id+' '+AccesskeyElement.className); if ( !AccesskeyElement.disabled ) { ClassNames = AccesskeyElement.className.split(' '); AccesskeyFound = false; for ( j=0; j<ClassNames.length; j++ ) { if ( AccesskeyFound ) { if ( typeof Accesskeys[ClassNames[j]] === 'undefined' ) { Accesskeys[ClassNames[j]] = []; } Accesskeys[ClassNames[j]].push(AccesskeyElement.id); break; } if ( ClassNames[j] === 'accesskey') { AccesskeyFound = true; } } } else { if ( DEBUG ) { console.log(PC+AccesskeyElement.id+' is disabled.',CF); } } } // Loop thru Accesskeys. if ( DEBUG ) { console.log(PC+'Accesskeys='+JSON.stringify(Accesskeys),CI); } if ( DEBUG ) { console.groupEnd(); } } // AccesskeysDisable() // Disable accesskeys. function AccesskeysDisable(by) { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log(`${PC}AccesskeysDisable[] by=${by}`,CG); } else { console.log(`${PC}AccesskeysDisable[] by=${by}`,CH); } Accesskeys = {}; } // AccesskeysKeyDown(evt) // Handle keyup events. let ProperAccesskey = false; let AccesskeysKeyDown = function(evt) { let DEBUG = DEBUG_OFF; let DEBUG_ProperAccesskey_DoNotClickButton = false; let Return; if ( !evt.key ) { console.log(`${PC}evt.key is not available.`,CE); return; } if ( !evt.key.toLowerCase ) { console.log(`${PC}evt.key.toLowerCase is not available.`,CE); return; } let AccesskeyStroke = evt.key.toLowerCase(); if ( DEBUG ) { console.group(PC+'AccesskeysKeyDown[] key='+AccesskeyStroke+' id='+evt.target.id+' type='+evt.type+' keyCode='+evt.keyCode+' alt='+evt.altKey+' ctrl='+evt.ctrlKey+' shift='+evt.shiftKey,CG); } //console.log(JSON.stringify(evt)); // Find out if this is a proper accesskey. ProperAccesskey = true; let AccesskeyElement; if ( evt.altKey ) { ProperAccesskey = false; if ( DEBUG ) { console.log(PC+'alt key. ProperAccesskey=false.',CF); } } else { if ( evt.ctrlKey ) { ProperAccesskey = false; if ( DEBUG ) { console.log(PC+'ctrl key. ProperAccesskey=false.',CF); } } else { if ( evt.shiftKey ) { ProperAccesskey = false; if ( DEBUG ) { console.log(PC+'shift key. ProperAccesskey=false.',CF); } } else { if ( ( evt.keyCode < 48 || evt.keyCode > 57 ) && ( evt.keyCode < 65 || evt.keyCode > 90 ) ) { ProperAccesskey = false; if ( DEBUG ) { console.log(PC+'not a-z0-9. ProperAccesskey=false.',CF); } } else { // AccesskeyStroke is not a-z0-9. if ( typeof Accesskeys[AccesskeyStroke] === 'undefined' ) { ProperAccesskey = false; if ( DEBUG ) { console.log(PC+'Accesskeys['+AccesskeyStroke+'] undefined. ProperAccesskey=false.',CF); } } else { // Valid accesskey. console.log(`${PC}Accesskeys[${AccesskeyStroke}=${Accesskeys[AccesskeyStroke]}`,CD); for ( let aki=0; aki<Accesskeys[AccesskeyStroke].length; aki++ ) { // Loop thru Accesskeys. AccesskeyElement = document.getElementById(Accesskeys[AccesskeyStroke][aki]); if ( AccesskeyElement.disabled ) { ProperAccesskey = false; if ( DEBUG ) { console.log(PC+'Accesskeys['+AccesskeyStroke+'] disabled. ProperAccesskey=false.',CF); } break; } // AccesskeyElement.disabled. } // Loop thru Accesskeys. } // Accesskeys[AccesskeyStroke] === 'undefined'. } // AccesskeyStroke is not a-z0-9. } // shiftKey. } // ctrlKey. } // altKey. if ( !ProperAccesskey ) { // Is this not a proper accesskey. if ( DEBUG ) { console.log(PC+'ProperAccesskey=false.',CF); } // Check for AccesskeySpecialFunction. if ( DEBUG ) { console.log(`${PC}evt.keyCode=${evt.keyCode}`,CL); } if ( AccesskeySpecialFunction[evt.keyCode] !== 'undefined' ) { if ( DEBUG ) { console.log(`${PC}eval[${AccesskeySpecialFunction[evt.keyCode]}]`,CD); } eval(AccesskeySpecialFunction[evt.keyCode]); } else { if ( DEBUG ) { console.log(`${PC}AccesskeySpecialFunction[${[evt.keyCode]} is not set.`,CF); } } Return = true; } else { // Is this not a proper accesskey. // This is a proper accesskey. if ( DEBUG ) { console.log(PC+'ProperAccesskey=true. stopPropagation()',CT); } event.stopPropagation(); Return = false; if ( evt.type === 'keydown' ) { // Is this a keydown? if ( DEBUG ) { console.log(`${PC}AccesskeyElement.type=${AccesskeyElement.type}`,CI); } AccesskeyElement.blur(); switch ( AccesskeyElement.type ) { // switch AccesskeyElement.type. case 'button': case 'submit': if ( !DEBUG_ProperAccesskey_DoNotClickButton ) { AccesskeyElement.click(); } else { console.log(PC+AccesskeyStroke+' accesskey for '+AccesskeyElement.id+' skipped because DEBUG_ProperAccesskey_DoNotClickButton is true.',CF); } break; case 'checkbox': AccesskeyElement.click(); break; case 'number': AccesskeyElement.focus(); break; case 'radio': AccesskeyElement.click(); break; case 'select-one': AccesskeyElement.focus(); AccesskeyElement.click(); event.stopPropagation(); break; case 'text': AccesskeyElement.focus(); break; default: console.log(`${PC}AccesskeyElement.type ${AccesskeyElement.type} not acted on.`,CF); } // switch AccesskeyElement.type. } // Is this a keydown? } // Is this not a proper accesskey. if ( DEBUG ) { console.log(`${PC}Return=${Return}`,CD); } if ( DEBUG ) { console.groupEnd(); } return Return; }; // END AccesskeysKeyDown. // Avoid `console` errors in browsers that lack a console. (function() { let method; let noop = function noop() {}; let methods = [ 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn' ]; let length = methods.length; let console = (window.console = window.console || {}); while ( length-- ) { method = methods[length]; // Only stub undefined methods. if ( !console[method] ) { console[method] = noop; } } }()); // END Avoid `console` errors in browsers that lack a console. /** / // BackspaceTrap() // To possibly override backspace keypress. // Some browsers use the backspace to go back a page. This function stops that behavior. // All backspaces are trapped if the element triggering the backspace is [object HTMLBodyElement]. let BackspaceTrap = function(event) { let DEBUG = false; if ( DEBUG ) { console.groupCollapsed(PC+'BackspaceTrap[event.type='+event.type+']',CG); } let keynum; if ( window.event ) { // eg. IE. keynum = window.event.keyCode; } else if ( event.which ) { // eg. Firefox. keynum = event.which; } //console.info(' typeof event.target='+(typeof event.target)+' event.target.id='+event.target.id+' Object.prototype.toString.call='+Object.prototype.toString.call(event.target)); //if ( keynum == 8 && event.target.id == '' ) {} // Is this a backspace code 8 and target has no id? if ( keynum === 8 && Object.prototype.toString.call(event.target) === '[object HTMLBodyElement]' ) { // Is this a backspace code 8 and target has no id? console.log(PC+'backspace trapped.',CW); event.stopPropagation(); if ( DEBUG ) { console.groupEnd(); } return false; // Trap the backspace. } else { if ( DEBUG ) { console.log(PC+'keynum='+keynum+' passed thru.',CI); } if ( event.type === 'keydown' ) { if ( DEBUG ) { console.groupEnd(); } //return AccesskeysKeyDown(event); // Check AccesskeysKeyDown to allow the keydown. return true; // Allow the keypress. } else { if ( DEBUG ) { console.groupEnd(); } return true; // Allow the keypress. } } // Is this a backspace code 8 and target has no id? }; document.onkeydown = BackspaceTrap; // IE, Firefox, Safari //document.onkeypress = BackspaceTrap; // Only Opera needs the backspace nullifying in onkeypress // END BackspaceTrap. /**/ // ClearSelectedText() // Clear any text selection function ClearSelectedText() { if (window.getSelection) { if (window.getSelection().empty) { // Chrome window.getSelection().empty(); } else if (window.getSelection().removeAllRanges) { // Firefox window.getSelection().removeAllRanges(); } } else if (document.selection) { // IE? document.selection.empty(); } } // END ClearSelectedText. // ColorSelect(e) // Color the select options. // Selected option backgroundColor is set to #af3. // The originally selected option backgroundColor is set to #aaf. let ColorSelect_OriginalOption = {}; // Remember the originally selected option. function ColorSelect(e) { let DEBUG = DEBUG_OFF; if ( e && e.id ) { if ( DEBUG ) { console.groupCollapsed(PC+'ColorSelect[e.id='+e.id+']',CG); } if ( typeof ColorSelect_OriginalOption[e.id] === 'undefined' ) { ColorSelect_OriginalOption[e.id] = e.options[e.selectedIndex].value; if ( DEBUG ) { console.log(PC+'ColorSelect_OriginalOption['+e.id+'] set to '+ColorSelect_OriginalOption[e.id],CS); } } if ( DEBUG ) { console.log(TB+'ColorSelect_OriginalOption['+e.id+']='+ColorSelect_OriginalOption[e.id]); } for ( let o=0; o<e.options.length; o++ ) { if ( DEBUG ) { console.log(TB+'e.options['+o+'].disabled='+e.options[o].disabled); } if ( !e.options[o].disabled ) { if ( e.options[o].value !== ColorSelect_OriginalOption[e.id] ) { e.options[o].style.backgroundColor = '#fff'; } else { e.options[o].style.backgroundColor = '#aaf'; } if ( DEBUG ) { console.log(TB+'e.options['+o+'].style.backgroundColor='+e.options[o].style.backgroundColor); } } } e.options[e.selectedIndex].style.backgroundColor = '#af3'; for ( o=0; o<e.options.length; o++ ) { if ( DEBUG ) { console.log(TB+'e.options['+o+'].style.backgroundColor='+e.options[o].style.backgroundColor); } } if ( DEBUG ) { console.groupEnd(); } } else { console.log(PC+TB+'ColorSelect[e] e is undefined.',CE); } } // END ColorSelect. // ColorSelectAttach() // Add 'change' EventListener 'ColorSelect(this);' to all select elements. function ColorSelectAttach() { let selects = document.getElementsByTagName('select'); // Get all selects. console.log('selects.length='+selects.length); for ( let i=0; i<selects.length; i++ ) { // Loop thru selects. selects[i].addEventListener('change',function(){ColorSelect(this);}); // Add change EventListener. ColorSelect(selects[i]); } // Loop thru selects. } // END ColorSelectAttach. // ElementBounds(elementOrId) // Return left, top, right, bottom, width, height, border, margin, and padding of an element. // elementOrId = element.id or element to check. // { left, top, right, bottom, width, height, border{ left, top, right, bottom }, margin{left, top, right, bottom }, padding{ left, top, right, bottom } }. function ElementBounds(elementOrId,by) { let DEBUG = DEBUG_OFF; let e; let eId; // Get element and element.id. if ( typeof elementOrId === 'string' ) { // elementOrId is the element.id. eId = elementOrId; e = document.getElementById(eId); if ( DEBUG ) { console.groupCollapsed(`${PC}ElementBounds[eId=${eId}] by=${by}`,CG); }// } else if ( typeof elementOrId === 'object' ) { // eId is the element. e = elementOrId; if ( e.id ) { eId = e.id; if ( DEBUG ) { console.groupCollapsed(`${PC}ElementBounds[eId=${eId}] by=${by}`,CG); }// } else { eId = ''; if ( DEBUG ) { console.groupCollapsed(`${PC}ElementBounds[tagName=${eId.tagName}] by=${by}`,CG); }// } } else { e = false; eId = ''; if ( DEBUG ) { console.groupCollapsed(`${PC}ElementBounds[???] eId='' by=${by}`,CG); }// if ( DEBUG ) { console.log(`${PC}eId is not a string or object.`,CE); } } let left = 0; let top = 0; let right = 0; let bottom = 0; let width = 0; let height = 0; let border = { left:0, top:0, right:0, bottom:0 }; let margin = { left:0, top:0, right:0, bottom:0 }; let padding = { left:0, top:0, right:0, bottom:0 }; if ( e ) { width = parseFloat(e.offsetWidth); height = parseFloat(e.offsetHeight); let style = e.currentStyle || window.getComputedStyle(e); border.left = parseFloat(style.borderLeftWidth.replace('px','')); border.top = parseFloat(style.borderTopWidth.replace('px','')); border.right = parseFloat(style.borderRightWidth.replace('px','')); border.bottom = parseFloat(style.borderBottomWidth.replace('px','')); margin.left = parseFloat(style.marginLeft.replace('px','')); margin.top = parseFloat(style.marginTop.replace('px','')); margin.right = parseFloat(style.marginRight.replace('px','')); margin.bottom = parseFloat(style.marginBottom.replace('px','')); padding.left = parseFloat(style.paddingLeft.replace('px','')); padding.top = parseFloat(style.paddingTop.replace('px','')); padding.right = parseFloat(style.paddingRight.replace('px','')); padding.bottom = parseFloat(style.paddingBottom.replace('px','')); // Get the left and top by walking up the parent elements. let eWalk = e; while( eWalk ) { // && eWalk.tagName && eWalk.tagName !== "BODY" && eWalk.id !== 'sectionId_1' left += parseFloat(eWalk.offsetLeft); top += parseFloat(eWalk.offsetTop); if ( DEBUG ) { console.log(`${PC}${TB}eWalk.id=${eWalk.id} tagName=${eWalk.tagName} left=${left} top=${top}`,CL); } eWalk = eWalk.offsetParent; } right = left + width; bottom = top + height; } else { if ( DEBUG ) { console.log(`${PC}No element with id=${eId} found.`,CE); } } let Return = { left:left, top:top, right:right, bottom:bottom, width:width, height:height, border:{ left:border.left, top:border.top, right:border.right, bottom:border.bottom }, margin:{ left:margin.left, top:margin.top, right:margin.right, bottom:margin.bottom }, padding:{ left:padding.left, top:padding.top, right:padding.right, bottom:padding.bottom } } if ( DEBUG ) { console.groupEnd(); } if ( DEBUG ) { console.log(`${PC}ElementBounds=${JSON.stringify(Return)}`,CI); } return Return; } // END ElementBounds. // elementLeftTop(element, by) // Returns left and top of an element. // element = element to check. function elementLeftTop(element,by) { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('elementLeftTop[element.id='+element.id+' by='+by+']'); } let left = 0; let top = 0; while( element && element.tagName && element.tagName !== "BODY" ) { let thisLeft = element.offsetLeft; left += thisLeft; let thisTop = element.offsetTop; top += thisTop; if ( DEBUG ) { console.log('element.tagName='+element.tagName+' element.id='+element.id+' element.style.position='+element.style.position+' thisLeft='+thisLeft+' thisTop='+thisTop+' left='+left+' top='+top); } element = element.offsetParent; } return { left: left, top: top }; } // END elementLeftTop. /** / // errordialog(msg, url, linenumber) // Display javascript errors at the top of the browser window. function errordialog(msg, url, linenumber) { let dialog = document.createElement("div"); dialog.className = 'errordialog'; dialog.innerHTML = ' <b class="error">JavaScript error:</b> ' + msg; if ( typeof url !== 'undefined' ) dialog.innerHTML += ' at ' + url + ':' + linenumber; dialog.innerHTML += '.'; document.body.appendChild(dialog); return true; } // END errordialog. window.onerror=function(msg, url, linenumber){ return errordialog(msg, url, linenumber) } // END Attach onerror. /**/ // eventHide(UTRu) // Hide this event content. function eventHide(UTRu) { if ( DEBUG_SeeEventsFleetsTechs ) { console.log('eventHide['+UTRu+']'); } TRstatus[UTRu] = false; if ( DEBUG_SeeEventsFleetsTechs ) { console.log('rowShow[eventShow_'+UTRu+'];'); } rowShow('eventShow_'+UTRu); if ( DEBUG_SeeEventsFleetsTechs ) { console.log('rowHide[eventContent_'+UTRu+'];'); } rowHide('eventContent_'+UTRu); } // eventHideAll(userId, turn) // Hide all event content for this turn. function eventHideAll(userId, turn) { if ( DEBUG_SeeEventsFleetsTechs ) { console.log('eventHideAll['+userId+', '+turn+']'); } document.getElementById('allEventsShow_'+userId+'_'+turn).style.display = 'inline'; // See all shown. document.getElementById('allEventsHide_'+userId+'_'+turn).style.display = 'none'; // Hide all hidden. for ( let i=0; i<TurnRoundIds[userId][turn].length; i++ ) { let UTRu = userId+'_'+turn+'_'+TurnRoundIds[userId][turn][i]; eventHide(UTRu); } } // eventShow(UTRu) // Show this event content. function eventShow(UTRu) { if ( DEBUG_SeeEventsFleetsTechs ) { console.log('eventShow['+UTRu+']'); } TRstatus[UTRu] = true; if ( DEBUG_SeeEventsFleetsTechs ) { console.log('rowHide[eventShow_'+UTRu+'];'); } rowHide('eventShow_'+UTRu); if ( DEBUG_SeeEventsFleetsTechs ) { console.log('rowShow[eventContent_'+UTRu+'];'); } rowShow('eventContent_'+UTRu); } // eventShowAll(userId, turn) // Show all event content for this turn. function eventShowAll(userId, turn) { if ( DEBUG_SeeEventsFleetsTechs ) { console.log('eventShowAll['+userId+', '+turn+']'); } document.getElementById('allEventsShow_'+userId+'_'+turn).style.display = 'none'; // See all hidden. document.getElementById('allEventsHide_'+userId+'_'+turn).style.display = 'inline'; // Hide all shown. for ( let i=0; i<TurnRoundIds[userId][turn].length; i++ ) { let UTRu = userId+'_'+turn+'_'+TurnRoundIds[userId][turn][i]; eventShow(UTRu); } } // eventTurnHide(userId, turn) // Hide all turn Events. function eventTurnHide(userId, turn) { if ( DEBUG_SeeEventsFleetsTechs ) { console.log('eventTurnHide['+userId+', '+turn+']'); } if ( DEBUG_SeeEventsFleetsTechs ) { console.log('TurnRoundIds['+userId+']['+turn+']='+TurnRoundIds[userId][turn]); } for ( let i=0; i<TurnRoundIds[userId][turn].length; i++ ) { let TRu = turn+'_'+TurnRoundIds[userId][turn][i]; let UTRu = userId+'_'+turn+'_'+TurnRoundIds[userId][turn][i]; if ( DEBUG_SeeEventsFleetsTechs ) { console.log('TRstatus['+userId+']['+TRu+']='+TRstatus[userId][TRu]); } if ( DEBUG_SeeEventsFleetsTechs ) { console.log('rowHide[eventShow_'+UTRu+'];'); } rowHide('eventShow_'+UTRu); if ( DEBUG_SeeEventsFleetsTechs ) { console.log('rowHide[eventContent_'+UTRu+'];'); } rowHide('eventContent_'+UTRu); } } // eventTurnShow(userId,turn) // Show turn Events based on their current status. function eventTurnShow(userId, turn) { console.log('eventTurnShow['+turn+']'); console.log('TurnRoundIds['+userId+', '+turn+']='+TurnRoundIds[userId][turn]); for ( let i=0; i<TurnRoundIds[userId][turn].length; i++ ) { let TRu = turn+'_'+TurnRoundIds[userId][turn][i]; let UTRu = userId+'_'+turn+'_'+TurnRoundIds[userId][turn][i]; console.log('TRstatus['+userId+']['+TRu+']='+TRstatus[userId][TRu]); if ( TRstatus[UTRu] ) { console.log('rowHide[eventShow_'+UTRu+'];'); rowHide('eventShow_'+UTRu); console.log('rowShow[eventContent_'+UTRu+'];'); rowShow('eventContent_'+UTRu); } else { console.log('rowShow[eventShow_'+UTRu+'];'); rowShow('eventShow_'+UTRu); console.log('rowHide[eventContent_'+UTRu+'];'); rowHide('eventContent_'+UTRu); } } } // EPPZScrollTo.scrollVerticalToElementById(id, pad) // Scroll to element with animation (slow) // id = The id of the element to scroll to. // pad = Top padding to apply above element. var EPPZScrollTo = { /* Helpers. */ // EPPZScrollTo.documentVerticalScrollPosition // Returns scroll top. documentVerticalScrollPosition: function() { if (self.pageYOffset) { return self.pageYOffset; } // Firefox, Chrome, Opera, Safari. if (document.documentElement && document.documentElement.scrollTop) { return document.documentElement.scrollTop; } // Internet Explorer 6 (standards mode). if (document.body.scrollTop) { return document.body.scrollTop; } // Internet Explorer 6, 7 and 8. return 0; // None of the above. }, // EPPZScrollTo.viewportHeight() // Returns the viewport height. viewportHeight: function() { return (document.compatMode === "CSS1Compat") ? document.documentElement.clientHeight : document.body.clientHeight; }, // EPPZScrollTo.documentHeight() // Returns the document height. documentHeight: function() { return (document.height !== undefined) ? document.height : document.body.offsetHeight; }, // EPPZScrollTo.documentMaximumScrollPosition() // Returns the maximum scroll position. documentMaximumScrollPosition: function() { return this.documentHeight() - this.viewportHeight(); }, // EPPZScrollTo.elementVerticalClientPositionById(id) // Returns the top position of the element. elementVerticalClientPositionById: function(id) { var element = document.getElementById(id); var rectangle = element.getBoundingClientRect(); return rectangle.top; }, /* Animation tick. */ // EPPZScrollTo.scrollVerticalTickToPosition(currentPosition, targetPosition) // Scroll from currentPosition to targetPosition scrollVerticalTickToPosition: function(currentPosition, targetPosition) { var filter = 0.2; var fps = 30; var difference = parseFloat(targetPosition) - parseFloat(currentPosition); // Snap, then stop if arrived. var arrived = (Math.abs(difference) <= 0.5); if (arrived) { // Apply target. scrollTo(0.0, targetPosition); return; } // Filtered position. currentPosition = (parseFloat(currentPosition) * (1.0 - filter)) + (parseFloat(targetPosition) * filter); // Apply target. scrollTo(0.0, Math.round(currentPosition)); // Schedule next tick. setTimeout("EPPZScrollTo.scrollVerticalTickToPosition("+currentPosition+", "+targetPosition+")", (1000 / fps)); }, /* For public use. * @param id The id of the element to scroll to. * @param pad Top padding to apply above element. */ scrollVerticalToElementById: function(id, pad) { var element = document.getElementById(id); if (element === null) { console.log('Cannot find element with id \''+id+'\'.'); return; } var targetPosition = this.documentVerticalScrollPosition() + this.elementVerticalClientPositionById(id) - pad; var currentPosition = this.documentVerticalScrollPosition(); // Clamp. var maximumScrollPosition = this.documentMaximumScrollPosition(); if (targetPosition > maximumScrollPosition) { targetPosition = maximumScrollPosition; } // Start animation. this.scrollVerticalTickToPosition(currentPosition, targetPosition); } }; // formSubmit(e, formTask, formAction) // Submit the form while disabling the button. // Disable any "button" or "submit" that uses this function. This is to help stop multiple form submissions. // Because the button is disabled the value is not sent when the form is submitted. This function fixes that. // A hidden form element is created with the name and value of the button. // Additionally, you can set a new value or even create many name/value pairs. See examples below. // e = the element calling formSubmit. // formTask = Create task or other hidden form elements. // undefined = Create a hidden element with the name and value of the e element. // string = Create a hidden element with the name 'task' and the value of formTask. // array = Create hidden elements for each associative array pair. The index is the name and the value is the value. // If e is of type button or submit and the array does not contain the button name a hidden element with the name and value of the e element is also created. // formAction = The new form action. If formAction is undefined the form action is unchanged. // // 1) i.e. Call w/o formTask. // formSubmit(this) or formSubmit(this,'','/new_form_action/') // <input type="submit" name="task" value="ClickMe" onClick="formSubmit(this);"> // Will disable submit button and create a hidden element with the name "task" and the value "ClickMe" then submit the form. // // 2) i.e. Call with formTask value. // formSubmit(this,'County select') or formSubmit(this,'County select','/new_form_action/') // <input type="radio" name="county" value="McLeod" onChange="formSubmit(this,'County select');">McLeod // Will create a hidden element with the name "task" and the value "County select" then submit the form. // // 3) i.e. Call with formTask as an array of name/value pairs. // formSubmit(this,{'name1':'value1','name2':'value2'}) or formSubmit(this,{'name1':'value1','name2':'value2'},'/new_form_action/') // <input type="submit" name="task" value="ClickMe" onClick="formSubmit(this,{'name1':'value1','name2':'value2'});"> // Will disable submit button and create 3 hidden elements with the names "name1", "name2", and "task" with the values "value1", "value2", and "ClickMe" then submit the form. function formSubmit(e, formTask, formAction, DEBUG_formSubmit=false) { var DEBUG = DEBUG_OFF; if ( DEBUG_formSubmit ) { DEBUG = DEBUG_ON; } let index; if ( DEBUG ) { let eText = 'e=undefined'; if ( e ) { if ( e.id ) { eText = 'e.id='+e.id; } else { eText = 'e.tagName='+e.tagName; } } let formTaskText; if ( typeof formTask === 'object' && formTask !== null ) { formTaskText = JSON.stringify(formTask); } else { formTaskText = formTask; } if ( DEBUG ) { console.group(`${PC}formSubmit[${eText}, formTask=${JSON.stringify(formTask)} formAction=${formAction} DEBUG_formSubmit=${DEBUG_formSubmit}`,CG); }//Collapsed } let defaultName = 'task'; // Set default form element name. let formSubmit_return = false; ttHide(); // Hide any tooltip. UpdateAutoOff(); // Turn off the updateAuto timer. //if ( document.getElementById('pageContent') ) document.getElementById('pageContent').style.visibility = 'hidden'; // Hide the map. // Show page loading. //if ( !DEBUG ) { LoadingPleaseWait(); } e.className = "wait"; // Change the class of the button to wait. if ( e ) { // Is e defined? if ( DEBUG ) { console.log(`${PC}e.name=${e.name} e.type=${e.type} e.value=${e.value}`,CL); } if ( e.type === 'button' || e.type === 'submit' ) { // Is e a button? if ( DEBUG ) { console.log(`${PC}Button disabled.`,CW); } e.disabled = true; // Disable the button. } // Is e a button? form = formSubmit_GetForm(e); // Get form. if ( DEBUG ) { console.log(`${PC}Original form.name=${form.name} form.action=${form.action} form.target=${form.target}`,CI); } if ( typeof formAction !== 'undefined' ) { form.action = formAction; // If formAction then change the form action. if ( DEBUG ) { console.log(`${PC}form.action changed to ${form.action}`,CD); } } let el; if ( typeof formTask === 'undefined' ) { // Is formTask undefined or empty? || formTask === '' if ( DEBUG ) { console.log(`${PC}typeof formTask === 'undefined'`,CI); } // formTask is undefined, so set task to e.value. if ( e.name ) { // Does e have a name? // Yes, named button with no formTask, so create a hidden element with e.name and the e.value. el = document.createElement("input"); // Create the input element. el.type = "hidden"; // Set element type to hidden. el.name = e.name; // Set element name to e.name. el.value = e.value; // Set element value to e.value. if ( DEBUG ) { console.log(`${PC}Create element type==${el.type} name=${el.name} value=${el.value}`,CD); } form.appendChild(el); // Add the element to the form. } else { // Does e have a name? // No, create a hidden element with the name 'task' and the e.value. el = document.createElement("input"); // Create the input element. el.type = "hidden"; // Set element type to hidden. el.name = defaultName; // Set element name to e.name. el.value = e.value; // Set element value to e.value. if ( DEBUG ) { console.log(`${PC}Create element type==${el.type} name=${el.name} value=${el.value}`,CD); } form.appendChild(el); // Add the element to the form. } // Does e have a name? // // Is formTask undefined or empty? } else if ( typeof formTask === 'string' ) { // Is formTask a string? // formTask is a string so create task with formTask value. if ( DEBUG ) { console.log(`${PC}typeof formTask === 'string'`,CI); } el = document.createElement("input"); // Create the input element. el.type = "hidden"; // Set element type to hidden. el.name = defaultName; // Set element name to task. el.value = formTask; // Set element value to formTask value. if ( DEBUG ) { console.log(`${PC}Create element type==${el.type} name=${el.name} value=${el.value}`,CD); } form.appendChild(el); // Add the element to the form. // Is formTask a string? } else if ( typeof formTask === 'object' && formTask !== null ) { // Is formTask as object? // formTask is an object so create elements for each array item. if ( DEBUG ) { console.log(`${PC}typeof formTask === 'object'`,CI); } if ( DEBUG ) { console.log(`${PC}formTask=${JSON.stringify(formTask)}`,CL); } if ( e.type === 'button' || e.type === 'submit' || e.type === 'click' ) { eFound = false; } else { eFound = true; } // Setup for addition of hidden elements if e is a button, submit, or click. if ( DEBUG ) { if ( eFound ) { console.log(`${PC}eFound=${eFound}`,CT); } else { console.log(`${PC}eFound=${eFound}`,CF); } } for ( index in formTask ) {if(formTask.hasOwnProperty(index)) { // Loop thru formTask object. if ( DEBUG ) { console.log(`${PC}formTask index=${index}`,CL); } el = document.createElement("input"); // Create the input element. el.type = "hidden"; // Set element type to hidden. el.name = index; // Set element name to formTask index. if ( el.name === e.name ) { eFound = true; } el.value = formTask[index]; // Set element value to formTask[index] value. if ( DEBUG ) { console.log(`${PC}Create element type==${el.type} name=${el.name} value=${el.value}`,CD); } form.appendChild(el); // Add the element to the form. }} // Loop thru formTask object. if ( !eFound && ( e.type === 'button' || e.type === 'submit' ) ) { // The button name was not in the array? if ( DEBUG ) { console.log(`${PC}The button name was not in the array, check for button name to add.`,CL); } if ( e.name ) { if ( DEBUG ) { console.log(`${PC}The buttonhad a name, so add a hidden element for button.`,CI); } el = document.createElement("input"); // Create the input element. el.type = "hidden"; // Set element type to hidden. el.name = e.name; // Set element name to e.name. el.value = e.value; // Set element value to e.value. if ( DEBUG ) { console.log(`${PC}Create element type==${el.type} name=${el.name} value=${el.value}`,CD); } form.appendChild(el); // Add the element to the form. } else { if ( DEBUG ) { console.log(`${PC}The button did not have a name, so do not add element.`,CW); } } } // The button name was not in the array? // Is formTask as object? } else if ( !e.name && ( typeof formTask === 'undefined' || formTask === '' ) ) { // Unnamed button with no formTask or formAction. Simply submit the form. } else { if ( typeof(e) === 'object' ) { ename = ' e.name='+e.name; } else { ename = ''; } if ( typeof(formAction) === 'string' ) { aname = ' formAction='+formAction; } else { aname = ''; } alert('formSubmit() is not programmed for typeof(e)='+typeof(e)+ename+' typeof(formTask)='+typeof(formTask)+' typeof(formAction)='+typeof(formAction)+aname)+'. 850'; //if ( DEBUG ) { console.groupEnd(); } //return false; } if ( !DEBUG ) { LoadingPleaseWait(); formSubmit_return = true; //if ( DEBUG ) { console.groupEnd(); } form.submit(); //return true; } else { // DEBUG is true. console.log(`${PC}form.action=${form.action} form.target=${form.target}`,CL); //let myform = document.forms[2]; //console.dir(myform); //console.groupEnd(); LoadingPleaseWait(); //setTimeout(function(){ LoadingPleaseWait(); }, 5000); alert('Submit form '+form.name+' in 5 seconds. 868'); setTimeout(function(){ form.submit(); }, 5000); //return false; } } else { // Is e defined? if ( DEBUG ) { alert('e is undefined. 874'); } //if ( DEBUG ) { console.groupEnd(); } //return false; } // Is e defined? if ( DEBUG ) { console.groupEnd(); } if ( DEBUG ) { console.log(`${PC}formSubmit_return=${formSubmit_return}`,CL); } return formSubmit_return; } // END formSubmit. // getE(id,p,t,by) // Set e and eId global values. // id = id prefix. // p = planet number. // t = techunitId. (May be planet number for planet only elements) // Returns true if the element id_t_p exists, else returns false. function getE(id,p,t,by) { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('getE['+id+','+p+','+t+','+by+']'); } eId = id; if ( p !== undefined && p !== '' ) { eId += '_'+p; } if ( t !== undefined && t !== '' ) { eId += '_'+t; } if ( DEBUG ) { console.log('eId='+eId); } if ( document.getElementById(eId) ) { if ( DEBUG ) { console.log('eId='+eId); } e = document.getElementById(eId); if ( DEBUG ) { console.log('e.id='+e.id); } return e; } else { return false; } } // END getE. // formSubmit_GetForm(e) // Return the form elemnt. // e = Form element to get form from. // If e is not a form element return last form in document or create a new one.. function formSubmit_GetForm(e) { var DEBUG = DEBUG_OFF; if ( DEBUG ) { console.group(`${PC}formSubmit_GetForm[e.id=${e.id}]`,CG); }//Collapsed let Return = null; if ( DEBUG ) { console.log(`${PC}e.form=${e.form} e.form.name=${e.form.name}`,CL); } if ( e.form && e.form.name ) { Return = e.form; } else { if ( document.forms.length ) { Return = document.forms[document.forms.length-1]; } else { let my_form=document.createElement('FORM'); my_form.name='added_form'; my_form.method='POST'; my_form.action='/Play/'; document.body.appendChild(my_form); Return= document.forms[0]; } } if ( DEBUG ) { console.groupEnd(); } return Return; } // END formSubmit_GetForm. // getValue(id, p, t, by) // Set e and eId values and return e.value with cleanup. // id = id prefix. // p = planet number. // t = techunitId. // Returns false if the element id_t_p does not exist. function getValue(id, p, t, by) { // console.log('getValue[id='+id+', p='+p+', t='+t+', by='+by+']'); let DEBUG = DEBUG_OFF; let getValueE = getE(id,p,t,'getValue['+id+','+p+','+t+','+by+']'); if ( getValueE ) { let eValue = getValueE.value; // Get value. thisValue = parseInt(eValue); // Get quantity. if ( isNaN(thisValue) || thisValue < 0 ) { thisValue = ''; } // Cleanup bad number. if ( eValue !== thisValue ) { getValueE.value = thisValue; if ( DEBUG ) { console.log('The value has non-numeric character: eValue='+eValue+' thisValue = '+thisValue+' in getValue['+id+','+p+','+t+','+by+']'); } } if ( thisValue === '' ) { thisValue = 0; } if ( thisValue === 0 ) { getValueE.value = ''; } // Clear zero from element. return thisValue; } else { if ( DEBUG ) { console.log('document.getElementById('+getValueE.id+') is undefined in getValue['+id+','+p+','+t+','+by+']'); } return false; } } // END getValue. // Help(evt) // Control help button onClick, onMouseDown, onMouseOut, and onMouseOver. function Help(evt) { var DEBUG = DEBUG_OFF; evt = evt || window.event; if ( DEBUG ) { console.log(`${PC}evt.target=${evt.target} evt.type=${evt.type}`,CL); } if ( evt.type !== 'button' ) { // Is this a click or mouseover? // Yes, Show the tooltip or setup and open the help dialog. if ( DEBUG ) { console.group(`${PC}Help[evt.target.id=${evt.target.id}] evt.type=${evt.type}`,CG); }//Collapsed switch ( evt.type ) { case 'click': // Setup and open the help dialog. ttHide(); document.getElementById('help_title').innerHTML = evt.target.alt; let helpName = evt.target.id.substr(5); let URL = HTTP_ROOT + '/help/?' + helpName; if ( DEBUG ) { console.log(`${PC}helpName=${helpName} URL=${URL}`,CL); } document.getElementById('form_HelpDialog_action').value = URL; HelpDisplay(evt,helpName); break; case 'mouseover': // Show the tooltip. ttShow(evt.target.getAttribute('data-tt')+'.'); break; } } else { // Is this a click or mouseover? // No, The Window button was clicked. if ( DEBUG ) { console.group(`${PC}Help[] evt.type=${evt.type}`,CG); }//Collapsed let URL = document.getElementById('form_HelpDialog_action').value; let Title = URL.replace("_",' '); if ( DEBUG ) { console.log(`${PC}Open ${URL} in a new window.`,CD); } window.open(URL, 'Help', 'location=yes,height=570,width=520,scrollbars=yes,status=yes'); menuHide(); } // Is this a click or mouseover? if ( DEBUG ) { console.groupEnd(); } } // END help. // HelpDisplay(evt, helpName) // Display the help dialog. function HelpDisplay(evt, helpName) { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('HelpDisplay[helpName='+helpName+']'); } //if ( typeof event !== 'undefined' ) { evt = event; } else { evt = window.event; } //evt = evt || window.event; GetMouse_mxmy(evt); if ( DEBUG ) { console.log('mx='+mx+' my='+my); } MenuIdBegin = 'dbHelpDialog'; eMapMenu = document.getElementById(MenuIdBegin); if ( ( typeof MenuShownLast !== 'undefined' ) && MenuShownLast ) { menuHide('HelpDisplay:829'); } // Hide the last menu. MenuShownLast = MenuIdBegin; // Load help contents. let URI = HTTP_ROOT+'/help/'+helpName+'.php'; document.getElementById('help_contents').innerHTML = ''; UpdateInclude(URI, 'help_contents', evt.target.alt, "HelpNotFound('"+helpName+"');"); let targetLeft = mx; let targetTop = my; if ( DEBUG ) { console.log('targetLeft='+targetLeft+' targetTop='+targetTop); } // Get windowScrollLeft and windowScrollTop. let windowScrollLeft = ttAllGet? ttTrueBody.scrollLeft : window.pageXOffset; let windowScrollTop = ttAllGet? ttTrueBody.scrollTop : window.pageYOffset; if ( DEBUG ) { console.log('windowScrollLeft='+windowScrollLeft+' windowScrollTop='+windowScrollTop); } let root = document.compatMode === 'BackCompat'? document.body : document.documentElement; let isHorizScroll = root.scrollWidth>root.clientWidth; let isVertScroll = root.scrollHeight>root.clientHeight; if ( DEBUG ) { console.log('isHorizScroll='+isHorizScroll+' isVertScroll='+isVertScroll); } document.body.style.overflow = 'hidden'; let scrollbarSize = document.body.clientWidth; document.body.style.overflow = 'scroll'; scrollbarSize -= document.body.clientWidth; if ( !scrollbarSize ) { scrollbarSize = document.body.offsetWidth - document.body.clientWidth; } document.body.style.overflow = ''; if ( DEBUG ) { console.log('scrollbarSize='+scrollbarSize); } // Get winWidth and winHeight. let winWidth = 630; let winHeight = 460; let winSizeChanged = false; if (document.body && document.body.offsetWidth) { winWidth = document.body.offsetWidth; winHeight = document.body.offsetHeight; } if (document.compatMode === 'CSS1Compat' && document.documentElement && document.documentElement.offsetWidth ) { winWidth = document.documentElement.offsetWidth; winHeight = document.documentElement.offsetHeight; } if (window.innerWidth && window.innerHeight) { winWidth = window.innerWidth; winHeight = window.innerHeight; } if ( DEBUG ) { console.log('winWidth='+winWidth+' winHeight='+winHeight); } if ( isHorizScroll ) { winHeight -= scrollbarSize; winSizeChanged = true; if ( DEBUG ) { console.log('winHeight changed to '+winHeight+' because of horizontal scroll bar'); } } if ( isVertScroll ) { winWidth -= scrollbarSize; if ( DEBUG ) { console.log('winWidth changed to '+winWidth+' because of vertical scroll bar'); } winSizeChanged = true; } if ( winSizeChanged && DEBUG ) { console.log('winWidth='+winWidth+' winHeight='+winHeight); } // Set starting locationLeft and locationTop. let locationLeft = mx; let locationTop = my; if ( DEBUG ) { console.log('Starting position: locationLeft='+locationLeft+' locationTop='+locationTop); } // Display so menuWidth and menuHeight can be determined. eMapMenu.style.left = locationLeft+'px'; eMapMenu.style.top = locationTop+'px'; eMapMenu.style.display = 'block'; //eMapMenu.style.visibility = 'visible'; // Get menuWidth and menuHeight. let menuWidth = eMapMenu.offsetWidth + 2; let menuHeight = eMapMenu.offsetHeight + 2; if ( DEBUG ) { console.log('menuWidth='+menuWidth); } if ( DEBUG ) { console.log('menuHeight='+menuHeight); } // Center the menu on mouseX and place Y above mouse. locationLeft -= Math.round(menuWidth / 2); locationTop -= menuHeight; if ( DEBUG ) { console.log('Centered position: locationLeft='+locationLeft+' locationTop='+locationTop); } // Make sure window is not too far left. let Xchanged = false; if ( locationLeft < windowScrollLeft ) { Xchanged = true; locationLeft = windowScrollLeft; if ( DEBUG ) { console.log('Menu is too far left.'); } if ( DEBUG ) { console.log('Moved to left: locationLeft='+locationLeft); } } // Make sure window is not too high. let Ychanged = false; if ( locationTop < windowScrollTop ) { Ychanged = true; locationTop = windowScrollTop; if ( DEBUG ) { console.log('Menu is too high.'); } if ( DEBUG ) { console.log('Moved to top: locationTop='+locationTop); } } if ( !Xchanged ) { // Make sure window is not too far right. let menuRight = locationLeft + menuWidth - windowScrollLeft; // Get right side of menu. if ( DEBUG ) { console.log('menuRight='+menuRight); } if ( menuRight > winWidth) { locationLeft = locationLeft - menuRight + winWidth; if ( DEBUG ) { console.log('Menu is too far right.'); } if ( DEBUG ) { console.log('Moved to left: locationLeft='+locationLeft); } } } if ( !Ychanged ) { // Make sure window is not too low. This should never happen as you did click on it. let menuBottom = locationTop + menuHeight - windowScrollTop; // Get bottom of menu. if ( DEBUG ) { console.log('menuBottom='+menuBottom); } if ( menuBottom > winHeight) { locationTop = locationTop - menuBottom + winHeight; if ( DEBUG ) { console.log('Menu is too low.'); } if ( DEBUG ) { console.log('Moved to top: locationTop='+locationTop); } } } eMapMenu.style.left = locationLeft+'px'; eMapMenu.style.top = locationTop+'px'; } // END helpDisplay. // HelpNotFound(btnId) // Show help not written if empty or 404 error. // A 404 error will leave the Loading text in the help_contents td. function HelpNotFound(btnId) { let HelpContents = document.getElementById('help_contents').innerHTML; console.log('btnId='+btnId); if ( HelpContents === '' || HelpContents.substring(0,30) === '<em class="info bold">Loading ' ) { document.getElementById('help_contents').innerHTML = '<b class="warntext">Sorry, this help content has not yet been written.</b>'; document.getElementById('help_'+btnId).disabled = true; } } // END HelpNotFound. // htmlSafe(str) // Return an HTML safe string. function htmlSafe(str) { return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/(?:\r\n|\r|\n)/g, '<br>').replace(/"/g, '"'); } // END htmlSafe. // IncrementCounter(thisFunction) // Increment the function counter. Used to count the number of times a function is called. function IncrementCounter(thisFunction) { if (typeof thisFunction.counter === 'undefined' ) { thisFunction.counter = 0; } thisFunction.counter++; return thisFunction.counter; } // END IncrementCounter. // IsInViewport(e) // Return tru if the element is in the viewport else false. // e = The element to check. var IsInViewport = function (e) { var bounding = e.getBoundingClientRect(); return ( bounding.top >= 0 && bounding.left >= 0 && bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) && bounding.right <= (window.innerWidth || document.documentElement.clientWidth) ); }; // IsNumeric(n) // Returns true if n is numeric, else false. function IsNumeric(value) { return !isNaN(parseFloat(value)) && isFinite(value); } // END isNumeric. // // function IsUndefined(value) { //return value === undefined; console.log( typeof value ); return ( value === 'undefined' || value === null ); } // END IsUndefined. // LoadingPleaseWait() // Show Loading... and hide pageContent when a form is submitted. function LoadingPleaseWait() { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}LoadingPleaseWait[]`,CG); }//Collapsed //return; /** / if ( document.getElementById('pageHeader') ) { document.getElementById('pageHeader').style.display = 'none'; if ( DEBUG ) { console.log(`${PC}pageHeader hidden.`,CD); } } else { if ( DEBUG ) { console.log(`${PC}pageHeader not found.`,CW); } } if ( document.getElementById('pageContent') ) { document.getElementById('pageContent').style.display = 'none'; if ( DEBUG ) { console.log(`${PC}pageContent hidden.`,CD); } } else { if ( DEBUG ) { console.log(`${PC}pageContent not found.`,CW); } } if ( document.getElementById('pageFooter') ) { document.getElementById('pageFooter').style.display = 'none'; if ( DEBUG ) { console.log(`${PC}pageFooter hidden.`,CD); } } else { if ( DEBUG ) { console.log(`${PC}pageFooter not found.`,CW); } } /**/ // Hide dbMessageContents if ( document.getElementById('dbMessageContents') ) { document.getElementById('dbMessageContents').style.display = 'none'; } // Hide ttSpendingContents. if ( document.getElementById('ttSpendingContents') ) { document.getElementById('ttSpendingContents').style.display = 'none'; } let elements; // Hide all main. elements = document.getElementsByTagName('main'); for ( let i=0; i<elements.length; i++ ) { elements[i].style.display = 'none'; } // Hide all section. elements = document.getElementsByTagName('section'); for ( let i=0; i<elements.length; i++ ) { elements[i].style.display = 'none'; } // Hide all divs. elementss = document.getElementsByTagName('div'); for ( let i=0; i<elements.length; i++ ) { elements[i].style.display = 'none'; } // Hide all footer. elements = document.getElementsByTagName('footer'); for ( let i=0; i<elements.length; i++ ) { elements[i].style.display = 'none'; } if ( document.getElementById('pageContentLoading') ) { document.getElementById('pageContentLoading').style.display = 'block'; if ( DEBUG ) { console.log(`${PC}pageContentLoading shown.`,CD); } } else { if ( DEBUG ) { console.log(`${PC}pageContentLoading not found.`,CW); } } //if ( DEBUG ) { alert('pageContentLoading'); } if ( DEBUG ) { console.groupEnd(); } } // END LoadingPleaseWait. // moveDisplay(menuType, mXY, by) // Display the movement dialog. // menuType = the click event. // mXY = The XY of the menu to display. If undefined it will be determined by XY. function moveDisplay(menuType, mXY, by) { let DEBUG = DEBUG_OFF; if ( typeof mXY === 'undefined' ) { mXY = ''; } if ( DEBUG ) { console.groupCollapsed(`${PC}moveDisplay[menuType=${menuType} mXY=${mXY} XY=${XY}] by=${by}`,CG); } let hXY; let StarNote_div_Bounds; let StarNote_tbl_Bounds; if ( typeof mXY !== 'undefined' && mXY !== '' ) { MenuIdBegin = menuType + '_' + mXY; hXY = GetHexCenterCoords(mXY); if ( menuType === 'MapMenu' ) { MapMenu = document.getElementById('MapMenu_'+mXY); } //console.log('mx='+mx+' my='+my); //console.log('hXY.X='+hXY.X+' hXY.Y='+hXY.Y); } else { MenuIdBegin = menuType; hXY = GetHexCenterCoords(XY); //console.log('mx='+mx+' my='+my); //console.log('hXY.X='+hXY.X+' hXY.Y='+hXY.Y); } if ( DEBUG ) { console.log(PC+'hXY='+JSON.stringify(hXY),CL); } // Get map image top left. let canvasTopLeft = elementLeftTop(document.getElementById('canvasMapBase'),'moveDisplay_434'); // The top and left of the canvas. if ( DEBUG ) { console.log(PC+'canvasTopLeft='+JSON.stringify(canvasTopLeft),CL); } mx = hXY.X + canvasTopLeft.left;// + ( PadHoriz * sideC ); // Adjust the mouseX for mapImage_e X and image padding. my = hXY.Y + canvasTopLeft.top; // Adjust the mouseY for mapImage_e Y. if ( DEBUG ) { console.log('mx='+mx+' my='+my); } if ( DEBUG ) { console.log('MenuIdBegin='+MenuIdBegin+' mx='+mx+' my='+my); } if ( DEBUG ) { console.log('MenuOnClickEnabled='+MenuOnClickEnabled); } if ( MenuOnClickEnabled ) { // Is the menu onclick enabled? if ( movesToTextTimer ) { // Remove movement tooltip and redraw movement lines. if ( DEBUG ) { console.info(PC+'clearTimeout[movesToTextTimer='+movesToTextTimer+'];',CD); } clearTimeout(movesToTextTimer); MovementTooltipHide('site.js moveDisplay 1202 movesToTextTimer'); } if ( false ) { // Yes, it must be a drag. if ( DEBUG ) { console.info('e.id='+e.id); } menuDrag.startMoving(evt); } else { // Is this a MapMenuHeader element. // No, show the menu. let eMapMenu; ttHide(); // Hide tooltip. // Get mapMenu, if ( document.getElementById(MenuIdBegin) ) { eMapMenu = document.getElementById(MenuIdBegin); eMapMenu.style.opacity = 1; } else { eMapMenu = false; } if ( MenuShownLast ) { menuHide('moveDisplay 860'); } // Hide the last menu. MenuShownLast = MenuIdBegin; if ( eMapMenu ) { // Is there a map menu? if ( DEBUG ) { console.log('eMapMenu.id='+eMapMenu.id); } let targetLeft = mx; let targetTop = my; if ( DEBUG ) { console.log('targetLeft='+targetLeft+' targetTop='+targetTop); } // Get windowScrollLeft and windowScrollTop. let windowScrollLeft = ttAllGet? ttTrueBody.scrollLeft : window.pageXOffset; let windowScrollTop = ttAllGet? ttTrueBody.scrollTop : window.pageYOffset; if ( DEBUG ) { console.log('windowScrollLeft='+windowScrollLeft+' windowScrollTop='+windowScrollTop); } let root = document.compatMode === 'BackCompat'? document.body : document.documentElement; let isHorizScroll = root.scrollWidth>root.clientWidth; let isVertScroll = root.scrollHeight>root.clientHeight; if ( DEBUG ) { console.log('isHorizScroll='+isHorizScroll+' isVertScroll='+isVertScroll); } document.body.style.overflow = 'hidden'; let scrollbarSize = document.body.clientWidth; document.body.style.overflow = 'scroll'; scrollbarSize -= document.body.clientWidth; if ( !scrollbarSize ) { scrollbarSize = document.body.offsetWidth - document.body.clientWidth; } document.body.style.overflow = ''; if ( DEBUG ) { console.log('scrollbarSize='+scrollbarSize); } // Get winWidth and winHeight. let winWidth = 630; let winHeight = 460; let winSizeChanged = false; if (document.body && document.body.offsetWidth) { winWidth = document.body.offsetWidth; winHeight = document.body.offsetHeight; } if (document.compatMode === 'CSS1Compat' && document.documentElement && document.documentElement.offsetWidth ) { winWidth = document.documentElement.offsetWidth; winHeight = document.documentElement.offsetHeight; } if (window.innerWidth && window.innerHeight) { winWidth = window.innerWidth; winHeight = window.innerHeight; } if ( DEBUG ) { console.log('winWidth='+winWidth+' winHeight='+winHeight); } if ( isHorizScroll ) { winHeight -= scrollbarSize; winSizeChanged = true; if ( DEBUG ) { console.log('winHeight changed to '+winHeight+' because of horizontal scroll bar'); } } if ( isVertScroll ) { winWidth -= scrollbarSize; if ( DEBUG ) { console.log('winWidth changed to '+winWidth+' because of vertical scroll bar'); } winSizeChanged = true; } if ( winSizeChanged && DEBUG ) { console.log('winWidth='+winWidth+' winHeight='+winHeight); } // Set starting locationLeft and locationTop. let locationLeft = mx; let locationTop = my; if ( DEBUG ) { console.log('Starting position: locationLeft='+locationLeft+' locationTop='+locationTop); } // Display so menuWidth and menuHeight can be determined. eMapMenu.style.left = locationLeft+'px'; eMapMenu.style.top = locationTop+'px'; eMapMenu.style.display = 'block'; StarNote_div_Bounds = ElementBounds(MenuIdBegin,'moveDisplay 1181'); if ( DEBUG ) { console.log(`${PC}StarNote_div_Bounds=${JSON.stringify(StarNote_div_Bounds)}`,CL); } if ( menuType === 'dbStarNoteContents' && document.getElementById('tbl_StarNote')) { StarNote_tbl_Bounds = ElementBounds('tbl_StarNote','moveDisplay 1183'); if ( DEBUG ) { console.log(`${PC}StarNote_tbl_Bounds=${JSON.stringify(StarNote_tbl_Bounds)}`,CL); } eMapMenu.style.height = StarNote_tbl_Bounds.height+'px'; document.getElementById('tbl_StarNote').style.top = StarNote_div_Bounds.top+'px'; } else { if ( DEBUG ) { console.log(`tbl_StarNote not found.`,CF); } } StarNote_div_Bounds = ElementBounds(MenuIdBegin,'moveDisplay 1189'); if ( DEBUG ) { console.log(`${PC}StarNote_div_Bounds=${JSON.stringify(StarNote_div_Bounds)}`,CI); } //eMapMenu.style.visibility = 'visible'; // Get menuWidth and menuHeight. let menuWidth = eMapMenu.offsetWidth;// + 2; let menuHeight = eMapMenu.offsetHeight;// + 2; if ( DEBUG ) { console.log(`${PC}menuWidth=${menuWidth} menuWidth=${menuWidth}`,CL); } // Center the menu on mouseX and place Y above mouse. locationLeft -= Math.round(menuWidth / 2); locationTop -= menuHeight; if ( DEBUG ) { console.log(`${PC}Centered position: locationLeft=${locationLeft} locationTop=${locationTop}`,CL); } // Make sure window is not too far left. let Xchanged = false; if ( locationLeft < windowScrollLeft ) { Xchanged = true; locationLeft = windowScrollLeft; if ( DEBUG ) { console.log('Menu is too far left.'); } if ( DEBUG ) { console.log('Moved to left: locationLeft='+locationLeft); } } // Make sure window is not too high. let Ychanged = false; if ( locationTop < windowScrollTop ) { Ychanged = true; locationTop = windowScrollTop; if ( DEBUG ) { console.log('Menu is too high.'); } if ( DEBUG ) { console.log('Moved to top: locationTop='+locationTop); } } if ( !Xchanged ) { // Make sure window is not too far right. let menuRight = locationLeft + menuWidth - windowScrollLeft; // Get right side of menu. if ( DEBUG ) { console.log('menuRight='+menuRight); } if ( menuRight > winWidth) { locationLeft = locationLeft - menuRight + winWidth; if ( DEBUG ) { console.log('Menu is too far right.'); } if ( DEBUG ) { console.log('Moved to left: locationLeft='+locationLeft); } } } if ( !Ychanged ) { // Make sure window is not too low. This should never happen as you did click on it. let menuBottom = locationTop + menuHeight - windowScrollTop; // Get bottom of menu. if ( DEBUG ) { console.log('menuBottom='+menuBottom); } if ( menuBottom > winHeight) { locationTop = locationTop - menuBottom + winHeight; if ( DEBUG ) { console.log('Menu is too low.'); } if ( DEBUG ) { console.log('Moved to top: locationTop='+locationTop); } } } eMapMenu.style.left = locationLeft+'px'; eMapMenu.style.top = locationTop+'px'; StarNote_div_Bounds = ElementBounds(MenuIdBegin,'moveDisplay 1237'); if ( DEBUG ) { console.log(`${PC}StarNote_div_Bounds=${JSON.stringify(StarNote_div_Bounds)}`,CI); } if ( menuType === 'dbStarNoteContents' && document.getElementById('tbl_StarNote')) { StarNote_tbl_Bounds = ElementBounds('tbl_StarNote','moveDisplay 1239'); if ( DEBUG ) { console.log(`${PC}StarNote_tbl_Bounds=${JSON.stringify(StarNote_tbl_Bounds)}`,CI); } eMapMenu.style.height = StarNote_tbl_Bounds.height+'px'; document.getElementById('tbl_StarNote').style.top = '0px'; StarNote_tbl_Bounds = ElementBounds('tbl_StarNote','moveDisplay 1242'); if ( DEBUG ) { console.log(`${PC}StarNote_tbl_Bounds=${JSON.stringify(StarNote_tbl_Bounds)}`,CL); } } } else { // Is there a map menu? console.log('In call to moveDisplay['+menuType+','+mXY+'] element '+MenuIdBegin+' does not exist.'); } // Is there a map menu? } // Is this a MapMenuHeader element. } else { // Is the menu onclick enabled? //if ( DEBUG ) { } console.info('moveDisplay disabled.'); } // Is the menu onclick enabled? if ( DEBUG ) { console.groupEnd(); } return false; } // END moveDisplay // menuDrag() // Allows player to drag the MapMenu to another location. let menuDrag = function() { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('menuDrag[]'); } return { startMoving : function(evt) { // The function that sets up the div coordinates to make it move. Executed on the onmousedown event on the div. if ( DEBUG ) { console.info('menuDrag.startMoving[] Getting target...'); } evt = evt || window.event; if ( DEBUG ) { console.log('evt='+evt); } let eTarget = evt.target; if ( DEBUG ) { console.log('eTarget.id='+eTarget.id); } let XYsplit = eTarget.id.split('_'); // Split the target id to get XY. if ( DEBUG ) { console.log('XYsplit='+XYsplit); } if ( XYsplit[0] !== 'MapMenuHeader' ) { menuDrag.stopMoving(); } XY = XYsplit[1]; // Set XY. let eMapMenu = document.getElementById(MenuIdBegin); // Set element to move. if ( DEBUG ) { console.info('startMoving('+eMapMenu.id+')'); } GetMouse_mxmy(evt); // Set mx and my to the mouse position. divTop = eMapMenu.style.top; // We need the initial position of the div so that we can determine its final position on dragging. divLeft = eMapMenu.style.left; // We need the initial position of the div so that we can determine its final position on dragging. divTop = divTop.replace('px',''); // Remove px so that we can perform calculations on divTop. divLeft = divLeft.replace('px',''); // Remove px so that we can perform calculations on divLeft. let diffX = mx - divLeft, // We keep this value so that we can calculate the final position of the element. diffY = my - divTop; // We keep this value so that we can calculate the final position of the element. DOC.onmousemove = 'menuDrag.startMoving onmousemove function'; document.onmousemove = function(evt) { // Set onmousemove control to this function. evt = evt || window.event; GetMouse_mxmy(evt); aX = mx - diffX; // The current x-coordinate of the element. aY = my - diffY; // The current y-coordinate of the element. menuDrag.move(MenuIdBegin,aX,aY); // Function to actually move the element. }; if ( DEBUG || DEBUG_doc_on ) { console.log(`${PC}onmousemove set to ${DOC.onmousemove}${PC} @menuDrag startMoving 1286`,CI,CL); } }, stopMoving : function() { // This function gets executed when the user leaves the div alone. if ( DEBUG ) { console.info('menuDrag.stopMoving[]'); } if ( typeof CanvasMouseMoveListener !== 'undefined' ) { DOC.onmousemove = 'CanvasMouseMoveListener'; document.onmousemove = CanvasMouseMoveListener; // Set onmousemove control to CanvasMouseMoveListener. } else { DOC.onmousemove = 'ttControl'; document.onmousemove = ttControl; // Set onmousemove control to ttControl. } if ( DEBUG || DEBUG_doc_on ) { console.log(`${PC}onmousemove set to ${DOC.onmousemove}${PC} @menuDrag.stopMoving 1297`,CI,CL); } DOC.onmouseup = 'null'; document.onmouseup = null; // Stop mouseup. function(){} if ( DEBUG || DEBUG_doc_on ) { console.log(`${PC}onmouseup set to ${DOC.onmouseup}${PC} @menuDrag.stopMoving 1300`,CI,CL); } //e = false; // Make sure a new click starts with a fresh element. }, move : function(divid,xpos,ypos){ // Function to assign the style rules to the element. if ( DEBUG ) { console.info('menuDrag.move['+divid+','+xpos+','+ypos+']'); } let eMapMenu = document.getElementById(divid); eMapMenu.style.left = xpos + 'px'; eMapMenu.style.top = ypos + 'px'; DOC.onmouseup = 'menuDrag.stopMoving'; document.onmouseup = menuDrag.stopMoving; // Set the onmouseup to menuDrag.stopMoving. if ( DEBUG || DEBUG_doc_on ) { console.log(`${PC}onmouseup set to ${DOC.onmouseup}${PC} @menuDrag.move 1310`,CI,CL); } } }; }(); // END menuDrag. // menuHide(by) // Hide the XY menu. function menuHide(by) { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('menuHide() MenuShownLast='+MenuShownLast+' by='+by); } if ( document.getElementById(MenuShownLast) ) { document.getElementById(MenuShownLast).style.display = 'none'; } else { console.log('In call to menuHide() element '+MenuShownLast+' does not exist. by='+by); } ttHide(); MenuShownLast = false; return false; } // END menuHide. // GetMouse_mxmy(evt) // Set mx and my to the mouse position. function GetMouse_mxmy(evt) { let DEBUG = DEBUG_OFF; evt = evt || window.event; // Get the event. if ( DEBUG ) { console.groupCollapsed(`${PC}GetMouse_mxmy[evt.target=${evt.target}]`,CG); }// if ( DEBUG && evt.composedTarget) { console.log(`${PC}composedTarget.id=${evt.composedTarget.id}`,CL); } if ( DEBUG && evt.explicitOriginalTarget ) { console.log(`${PC}currentTarget.id=${evt.currentTarget.id}`,CL); } if ( DEBUG && evt.explicitOriginalTarget ) { console.log(`${PC}explicitOriginalTarget.id=${evt.explicitOriginalTarget.id}`,CL); } if ( DEBUG && evt.relatedTarget ) { console.log(`${PC}relatedTarget.id=${evt.relatedTarget.id}`,CL); } if ( DEBUG ) { console.log(`${PC}screenX=${evt.screenX} screenY=${evt.screenY}`,CL); } if ( DEBUG ) { console.log(`${PC}clientX=${evt.clientX} clientY=${evt.clientY}`,CL); } if ( DEBUG ) { console.log(`${PC}pageX=${evt.pageX} pageY=${evt.pageY}`,CL); } if ( DEBUG ) { console.log(`${PC}document.documentElement.scrollLeft=${document.documentElement.scrollLeft} document.documentElement.scrollTop=${document.documentElement.scrollTop}`,CL); } let New_mxmy = true; if ( DEBUG ) { console.log(`${PC}document.body.scrollLeft=${document.body.scrollLeft} document.body.scrollTop=${document.body.scrollTop}`,CL); } if ( /** /typeof evt !== 'undefined' && typeof evt.target !== 'undefined' &&/**/ evt.pageX ) { // Does the event have a target.id? mx = evt.pageX; my = evt.pageY; //if (evt.pageX) { mx = evt.pageX; } else if (evt.clientX) { mx = evt.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft); } else { mx = 0; } //if (evt.pageY) { my = evt.pageY; } else if (evt.clientY) { my = evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop); } else { my = 0; } Save_mxmy.mx = mx; Save_mxmy.my = my; } else { // Does the event have a target.id? mx = Save_mxmy.mx; my = Save_mxmy.my; New_mxmy = false; } // Does the event have a target.id? if ( DEBUG ) { console.groupEnd(); } if ( DEBUG ) { if ( New_mxmy ) { if ( DEBUG ) { console.log(`${PC}GetMouse_mxmy[] mx=${mx} my=${my}${PC} New mx my`,CS,CI); } } else { if ( DEBUG ) { console.log(`${PC}GetMouse_mxmy[] mx=${mx} my=${my}${PC} Old mx my`,CS,CW); } } } } // END GetMouse_mxmy. // Refresh_LastAccessAuto(sound, by) // Refresh the playergame lastAccess time and play sound automatically every SoundTimer seconds. function Refresh_LastAccessAuto(sound, by) { //console.log('Refresh_LastAccessOnce[sound='+sound+', by='+by+']'); SoundPlayByNameAuto(sound, true, 'Refresh_LastAccessAuto['+by+']'); } // END Refresh_LastAccessAuto. // Refresh_LastAccessOnce(sound, by) // Refresh the playergame lastAccess time and play sound if given. function Refresh_LastAccessOnce(sound, by) { //console.log('Refresh_LastAccessOnce[sound='+sound+', by='+by+']'); if ( typeof sound === 'undefined' ) { sound = 'false'; } let URI = HTTP_ROOT+'/Play/common/Refresh_LastAccess.php?sound='+sound+'&by=Refresh_LastAccessOnce[sound='+sound+',by='+by+']'; UpdateInclude(URI); if ( ( typeof sound !== 'undefined' ) && sound ) { SoundPlayByName(sound, 'Refresh_LastAccessOnce '+by); //SoundLastPlayedSound =''; } } // END Refresh_LastAccessOnce. // ScreenExit(e, action, name) // Exit play and submit form (Also set name or 'task' value). // Needs: <div id="divScreenExit" class="hide"></div> in body of page. // e = The object calling the function. // action = Replacement form action. // name = The form element name. If unset use the calling element name. If the calling element has no name use 'task'. function ScreenExit(e, action, name) { let DEBUG = DEBUG_OFF; let value; if ( e.value !== '' ) { value = e.value; if ( DEBUG ) { console.log('ScreenExit[value \''+value+'\',\''+action+'\',\''+name+'\']'); } } else { if ( e.name !== '' ) { value = e.name; if ( DEBUG ) { console.log('ScreenExit[name \''+value+'\',\''+action+'\',\''+name+'\']'); } } else { value = e.innerText; if ( DEBUG ) { console.log('ScreenExit[innerText \''+value+'\',\''+action+'\',\''+name+'\']'); } } } /** / This is now done in application.phpinc value = value.replace('B̲','B'); // Replace underlined B̲ with B. value = value.replace('D̲','D'); // Replace underlined D̲ with D. value = value.replace('d̲̲','d'); // Replace underlined d̲̲ with d. value = value.replace('N̲','N'); // Replace underlined N̲ with N. value = value.replace('o̲','o'); // Replace underlined o̲ with o. value = value.replace('x̲','x'); // Replace underlined x̲ with x. value = value.replace('Y̲','Y'); // Replace underlined Y̲ with Y. /**/ if ( DEBUG ) { console.log('value='+value); } ttHide(); // Hide any tooltip. UpdateAutoOff(); // Turn off the updateAuto timer. // Show page loading. LoadingPleaseWait(); e.className = "wait"; // Change the class of the button to wait. // Get the form. if ( DEBUG ) { console.log('document.forms='+document.forms); } if ( document.forms ) { // Document has forms. form = e.form; // Get form. if ( DEBUG ) { console.log('form.name='+form.name); } } else { if ( DEBUG ) { console.error('Document has no forms'); } } if ( DEBUG ) { console.log('form='+form.name); } // Get element name. If name is not set and calling e has no name, set name to 'task'; if ( DEBUG ) { console.log('name='+name); } if ( typeof name === 'undefined' || name === '' ) { if ( DEBUG ) { console.log('name is undefined or empty'); } if ( typeof e.name === 'undefined' || e.name === '' ) { if ( DEBUG ) { console.log('e.name is undefined or empty Set name=task'); } name = 'task'; } else { name = e.name; } } if ( DEBUG ) { console.log('name='+name); } if ( DEBUG ) { console.log('value='+value); } // Create name form element and set value. let fe = document.createElement("input"); // Create the input element. fe.type = 'hidden'; // Set element type to hidden. fe.name = name; // Set element name. fe.value = value; // Set element value to formTask value. form.appendChild(fe); // Add the element to the form. if ( DEBUG ) { console.log('Created element type='+fe.type+' name='+fe.name+' value='+fe.value); } // Change the form action if set. //if ( action != undefined ) { if ( typeof action !== 'undefined' && action !== '' ) { form.action = HTTP_ROOT+action; // Change the form action. if ( DEBUG ) { console.log('Changed the form action to: '+form.action); } } URLget('/Play/common/ScreenExit.php','divScreenExit'); // Exit the screen. if ( DEBUG ) { if ( document.getElementById('divScreenExit') ) { document.getElementById('divScreenExit').style.display = 'block'; } alert('ScreenExit() is submitting '+form.name); } //setTimeout(ScreenExit__Submit,100); // Submit the form in 100 milliseconds. setTimeout(function() { form.submit(); },100); // Submit the form in 100 milliseconds. } // END ScreenExit. // SeeHide_Events(see_hide) // Show or hide Events. function SeeHide_Events(see_hide) { let DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}SeeHide_Events[see_hide=${see_hide}] SeeHide_Events.Loaded=${SeeHide_Events.Loaded}`,CG); }//Collapsed if ( !SeeHide_Events.Loaded ) { if ( see_hide ) { see_hide = 1; } else { see_hide = 0; } let URI = HTTP_ROOT+'/Play/common/See/get_Events.php?GetEvents=1'; let elementId = 'div_See_Events'; let preloadText = '<br><br><span class="bold info">Loading Events. Please wait ...</span><br><br><br>'; let jsReturnCode = 'SeeHide_Events_Loaded('+see_hide+');' if ( DEBUG ) { console.log(`${PC}UpdateInclude('${HTTP_PROTOCOL}://${SERVER_NAME}${URI}&DEBUG=true','${elementId}','${preloadText}','${jsReturnCode}');`,CC); } UpdateInclude(URI,elementId,preloadText,jsReturnCode); } if ( see_hide ) { divShow('div_See_Events'); document.getElementById('hid_sEvent').value = 1; // Set hid_sEvent form element value to 1. // Set the btn_See_Events button to hide Events. document.getElementById('btn_See_Events').setAttribute('class','current small'); document.getElementById('btn_See_Events').onmouseover = function() { ttShow('Hide the list of Events.'); }; ttShow('Hide the list of Events.'); document.getElementById('btn_See_Events').onclick = function() { SeeHide_Events(false); }; } else { divHide('div_See_Events'); document.getElementById('hid_sEvent').value = 0; // Set hid_sEvent form element value to 0. // Set the btn_See_Events button to see Events. document.getElementById('btn_See_Events').setAttribute('class','small'); document.getElementById('btn_See_Events').onmouseover = function() { ttShow('Show your events.'); }; ttShow('Show your events.'); document.getElementById('btn_See_Events').onclick = function() { SeeHide_Events(true); }; } if ( DEBUG ) { console.groupEnd(); } } // END SeeHide_Events. SeeHide_Events.Loaded = false; // function SeeHide_Events_Loaded(see_hide) // Ensure events were loaded. function SeeHide_Events_Loaded(see_hide) { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}SeeHide_Events_Loaded[see_hide=${see_hide}]`,CG); }//Collapsed if ( document.getElementById('div_See_Events').innerHTML.search('Loading Events. Please wait ...') === -1 ) { // Did the events get loaded? if ( DEBUG ) { console.log(`${PC}Events loaded OK.`,CT); } SeeHide_Events.Loaded = true; } else { if ( DEBUG ) { console.log(`${PC}Events did not load. Re-calling SeeHide_Events[${see_hide}].`,CT); } setTimeout(function(){ SeeHide_Events(see_hide); }, 500); } if ( DEBUG ) { console.groupEnd(); } } // END SeeHide_Events_Loaded. // SeeHide_Fleets(see_hide) // Show or hide fleets and ships. // The div_See_Fleets is always written so it only eed to be shown or hidden. function SeeHide_Fleets(see_hide) { console.log('SeeHide_Fleets['+see_hide+']'); if ( see_hide ) { divShow('div_See_Fleets'); document.getElementById('hid_sFleet').value = 1; // Set hid_sFleet form element value to 1. // Set the btn_See_Fleets button to hide Fleets. document.getElementById('btn_See_Fleets').setAttribute('class','current small'); document.getElementById('btn_See_Fleets').onmouseover = function() { ttShow('Hide your fleets.'); }; ttShow('Hide your fleets.'); document.getElementById('btn_See_Fleets').onclick = function() { SeeHide_Fleets(false); }; } else { divHide('div_See_Fleets'); document.getElementById('hid_sFleet').value = 0; // Set hid_sFleet form element value to 0. // Set the btn_See_Fleets button to see Fleets. document.getElementById('btn_See_Fleets').setAttribute('class','small'); document.getElementById('btn_See_Fleets').onmouseover = function() { ttShow('Show a list of fleets.'); }; ttShow('See your fleets.'); document.getElementById('btn_See_Fleets').onclick = function() { SeeHide_Fleets(true); }; } } // END SeeHide_Fleets. // SeeHide_Map(see_hide) // Show or hide map. // The mapWrapper is always written so it only eed to be shown or hidden. function SeeHide_Map(see_hide) { console.log('SeeHide_Map['+see_hide+']'); if ( see_hide ) { divShow('mapWrapper'); document.getElementById('sel_See_Map').style.visibility = 'visible'; divShow('mapResize'); document.getElementById('hid_sMap').value = 1; // Set hid_sMap form element value to 1. // Set the btn_See_Map button to hide Map. document.getElementById('btn_See_Map').setAttribute('class','current small'); document.getElementById('btn_See_Map').onmouseover = function() { ttShow('Hide the game map.'); }; ttShow('Hide the game map.'); document.getElementById('btn_See_Map').onclick = function() { SeeHide_Map(false); }; } else { divHide('mapWrapper'); document.getElementById('sel_See_Map').style.visibility = 'hidden'; divHide('mapResize'); document.getElementById('hid_sMap').value = 0; // Set hid_sMap form element value to 0. // Set the btn_See_Map button to see Map. document.getElementById('btn_See_Map').setAttribute('class','small'); document.getElementById('btn_See_Map').onmouseover = function() { ttShow('Show the game map.'); }; ttShow('Show the game map.'); document.getElementById('btn_See_Map').onclick = function() { SeeHide_Map(true); }; } } // END SeeHide_Map. // SeeHide_Planets(see_hide) // Show or hide Planets. function SeeHide_Planets(see_hide) { let DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}SeeHide_Planets[see_hide=${see_hide}]`,CG); }//Collapsed if ( !SeeHide_Planets.Loaded ) { if ( see_hide ) { see_hide = 1; } else { see_hide = 0; } let URI = HTTP_ROOT+'/Play/common/See/get_Planets.php?GetPlanets=1'; let elementId = 'div_See_Planets'; let preloadText = '<br><br><span class="bold info">Loading Planets. Please wait ...</span><br><br><br>'; let jsReturnCode = 'SeeHide_Planets_Loaded('+see_hide+');' if ( DEBUG ) { console.log(`${PC}UpdateInclude('${HTTP_PROTOCOL}://${SERVER_NAME}${URI}&DEBUG=true','${elementId}','${preloadText}','${jsReturnCode}');`,CC); } UpdateInclude(URI,elementId,preloadText,jsReturnCode); } if ( see_hide ) { divShow('div_See_Planets'); document.getElementById('hid_sEvent').value = 1; // Set hid_sEvent form element value to 1. // Set the btn_See_Planets button to hide Planets. document.getElementById('btn_See_Planets').setAttribute('class','current small'); document.getElementById('btn_See_Planets').onmouseover = function() { ttShow('Hide your planets.'); }; ttShow('Hide your planets.'); document.getElementById('btn_See_Planets').onclick = function() { SeeHide_Planets(false); }; } else { divHide('div_See_Planets'); document.getElementById('hid_sEvent').value = 0; // Set hid_sEvent form element value to 0. // Set the btn_See_Planets button to see Planets. document.getElementById('btn_See_Planets').setAttribute('class','small'); document.getElementById('btn_See_Planets').onmouseover = function() { ttShow('Show your planets.'); }; ttShow('Show your planets.'); document.getElementById('btn_See_Planets').onclick = function() { SeeHide_Planets(true); }; } if ( DEBUG ) { console.groupEnd(); } } // END SeeHide_Planets. SeeHide_Planets.Loaded = false; // function SeeHide_Planets_Loaded(see_hide) // Ensure events were loaded. function SeeHide_Planets_Loaded(see_hide) { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}SeeHide_Planets_Loaded[see_hide=${see_hide}]`,CG); }//Collapsed if ( document.getElementById('div_See_Planets').innerHTML.search('Loading Planets. Please wait ...') === -1 ) { // Did the events get loaded? if ( DEBUG ) { console.log(`${PC}Planets loaded OK.`,CT); } SeeHide_Planets.Loaded = true; } else { if ( DEBUG ) { console.log(`${PC}Planets did not load. Re-calling SeeHide_Planets[${see_hide}].`,CT); } setTimeout(function(){ SeeHide_Planets(see_hide); }, 500); } if ( DEBUG ) { console.groupEnd(); } } // END SeeHide_Planets_Loaded. // SeeHide_Settings(see_hide) // Show or hide Settings. function SeeHide_Settings(see_hide) { let DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}SeeHide_Settings[see_hide=${see_hide}]`,CG); }//Collapsed if ( !SeeHide_Settings.Loaded ) { if ( see_hide ) { see_hide = 1; } else { see_hide = 0; } let URI = HTTP_ROOT+'/Play/common/See/get_Settings.php?GetSettings=1'; let elementId = 'div_See_Settings'; let preloadText = '<br><br><span class="bold info">Loading Settings. Please wait ...</span><br><br><br>'; let jsReturnCode = 'SeeHide_Settings_Loaded('+see_hide+');' if ( DEBUG ) { console.log(`${PC}UpdateInclude('${HTTP_PROTOCOL}://${SERVER_NAME}${URI}&DEBUG=true','${elementId}','${preloadText}','${jsReturnCode}');`,CC); } UpdateInclude(URI,elementId,preloadText,jsReturnCode); } if ( see_hide ) { divShow('div_See_Settings'); document.getElementById('hid_sEvent').value = 1; // Set hid_sEvent form element value to 1. // Set the btn_See_Settings button to hide Settings. document.getElementById('btn_See_Settings').setAttribute('class','current small'); document.getElementById('btn_See_Settings').onmouseover = function() { ttShow('Hide the list of Settings.'); }; ttShow('Show the game settings and your bank.'); document.getElementById('btn_See_Settings').onclick = function() { SeeHide_Settings(false); }; } else { divHide('div_See_Settings'); document.getElementById('hid_sEvent').value = 0; // Set hid_sEvent form element value to 0. // Set the btn_See_Settings button to see Settings. document.getElementById('btn_See_Settings').setAttribute('class','small'); document.getElementById('btn_See_Settings').onmouseover = function() { ttShow('Show the game settings and your bank.'); }; ttShow('Show the game settings and your bank.'); document.getElementById('btn_See_Settings').onclick = function() { SeeHide_Settings(true); }; } if ( DEBUG ) { console.groupEnd(); } } // END SeeHide_Settings. SeeHide_Settings.Loaded = false; // SeeHide_Settings_Loaded(see_hide) // Ensure settings were loaded. function SeeHide_Settings_Loaded(see_hide) { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}SeeHide_Settings_Loaded[see_hide=${see_hide}]`,CG); }//Collapsed if ( document.getElementById('div_See_Settings').innerHTML.search('Loading Settings. Please wait ...') === -1 ) { // Did the events get loaded? if ( DEBUG ) { console.log(`${PC}Settings loaded OK.`,CT); } SeeHide_Settings.Loaded = true; } else { if ( DEBUG ) { console.log(`${PC}Settings did not load. Re-calling SeeHide_Settings[${see_hide}].`,CT); } setTimeout(function(){ SeeHide_Settings(see_hide); }, 500); } if ( DEBUG ) { console.groupEnd(); } } // END SeeHide_Settings_Loaded. // SeeHide_Score(see_hide) // Show or hide score. // The div_See_Score is always written so it only eed to be shown or hidden. function SeeHide_Score(see_hide) { console.log('SeeHide_Score['+see_hide+']'); if ( see_hide ) { divShow('div_See_Score'); document.getElementById('hid_sScore').value = 1; // Set hid_sScore form element value to 1. // Set the btn_See_Score button to hide score. document.getElementById('btn_See_Score').setAttribute('class','current small'); document.getElementById('btn_See_Score').onmouseover = function() { ttShow('Hide the scores.'); }; ttShow('Hide the scores.'); document.getElementById('btn_See_Score').onclick = function() { SeeHide_Score(false); }; } else { divHide('div_See_Score'); document.getElementById('hid_sScore').value = 0; // Set hid_sScore form element value to 0. // Set the btn_See_Score button to see score. document.getElementById('btn_See_Score').setAttribute('class','small'); document.getElementById('btn_See_Score').onmouseover = function() { ttShow('Show the scores.'); }; ttShow('Show the scores.'); document.getElementById('btn_See_Score').onclick = function() { SeeHide_Score(true); }; } } // END SeeHide_Score. // SeeHide_Techs(see_hide) // Show or hide techs. // The div_See_Techs is always written so it only eed to be shown or hidden. function SeeHide_Techs(see_hide) { console.log('SeeHide_Techs['+see_hide+']'); if ( see_hide ) { divShow('div_See_Techs'); document.getElementById('hid_sTech').value = 1; // Set hid_sTech form element value to 1. // Set the btn_See_Techs button to hide Techs. document.getElementById('btn_See_Techs').setAttribute('class','current small'); document.getElementById('btn_See_Techs').onmouseover = function() { ttShow('Hide your technologies.'); }; ttShow('Hide your technologies.'); document.getElementById('btn_See_Techs').onclick = function() { SeeHide_Techs(false); }; } else { divHide('div_See_Techs'); document.getElementById('hid_sTech').value = 0; // Set hid_sTech form element value to 0. // Set the btn_See_Techs button to see Techs. document.getElementById('btn_See_Techs').setAttribute('class','small'); document.getElementById('btn_See_Techs').onmouseover = function() { ttShow('Show your technologies.'); }; ttShow('Show your technologies.'); document.getElementById('btn_See_Techs').onclick = function() { SeeHide_Techs(true); }; } } // END SeeHide_Techs. // SetGameSetting(e) // Set database, $_SESSION, and javascript values. function SetGameSetting(e) { var DEBUG = DEBUG_ON; if ( DEBUG ) { console.group(`${PC}SetGameSetting[e.id=${e.id}]`,CG); }//Collapsed ttHide(); let IdParts = e.id.split('_'); let radioName = IdParts[1]; let gameIndex = radioName.replace('Game','game'); let task = `Set${radioName}`; if ( DEBUG ) { console.log(`${PC}IdParts=${IdParts} radioName=${radioName} gameIndex=${gameIndex}`,CL); } // Get radio value. let value = 0; let radios = document.getElementsByName(radioName); for (let i = 0, length = radios.length; i < length; i++) { // Loop thru radio buttons. if (radios[i].checked) { // Is this button checked? value = radios[i].value; break; } // Is this button checked? } // Loop thru radio buttons. if ( GameInfo[gameIndex] != value ) { // Has the setting changed? // Yes, update the playergame table, $_SESSION variable, and GameInfo javascript values. if ( DEBUG ) { console.log(`${PC}${radioName} value has changed.`,CF); } GameInfo[gameIndex] = value; // Set GameInfo value. if ( DEBUG ) { console.log(`${PC}value=${value} GameInfo[${gameIndex}]=${GameInfo[gameIndex]}`,CL); } e.className = e.className.replace(' action',''); // Remove action from className. let URI = `${HTTP_ROOT}/Play/common/Set_Settings.php?task=${task}&userId=${userId}&gameId=${GameId}&field=${gameIndex}&value=${value}`; if ( DEBUG ) { console.log(`${PC}URI=${URI}`,CL); } if ( DEBUG ) { console.log(`${PC}UpdateInclude(${HTTP_PROTOCOL}://${SERVER_NAME}${URI}&DEBUG=true);`,CL); } UpdateInclude(URI,false); } else { // No, do nothing. if ( DEBUG ) { console.log(`${PC}${radioName} value is the current one.`,CT); } if ( DEBUG ) { console.log(`${PC}No changes were made`,CL); } } if ( DEBUG ) { console.groupEnd(); } } // END SetGameSetting. // SoundManage(e) // Manage sound settings. function SoundManage() { console.log('SoundManage[]'); if ( document.getElementById('menu_SoundSetting') ) { if ( document.getElementById('menu_SoundSetting').style.display !== 'block' ) { document.getElementById('menu_SoundSetting').style.display = 'block'; } else { document.getElementById('menu_SoundSetting').style.display = 'none'; } } } // END SoundManage. // SoundPlay(sound, by) // Play the soundfile. // If the sound is different from the last sound played: // play it immediately. // else // play it when getTime() > ( SoundLastPlayedTime + SoundTimer * 1000 ). let SoundLoaded; function SoundPlay(soundfile, by) { let DEBUG = DEBUG_OFF; let DEBUG_SOUND = DEBUG_OFF; SoundLoaded = false; //if(userId===3){DEBUG=true;} if ( DEBUG ) { console.group(PC+'SoundPlay[soundfile='+soundfile+'] by='+by,CG); } if ( document.getElementById("spn_PlaySound") ) { let PlaySound = false; document.getElementById("spn_PlaySound").innerHTML = ''; if ( typeof soundfile !== 'undefined' && soundfile !== '' ) { let SoundVolume = soundfile.substr(soundfile.length-5,1); let SoundFile = soundfile.replace(".wav",'').replace(".mp3",''); if ( DEBUG ) { console.log('SoundMute='+SoundMute+' SoundVolume='+SoundVolume+' SoundFile='+SoundFile); } // Get current time. let date = new Date(); let currentTime = date.getTime(); if ( SoundFile === SoundLastPlayedSound ) { // Is this sound the last one played? // Yes, check time. let playtime = SoundLastPlayedTime + SoundTimer * 1000 - 10; let difftime = currentTime - playtime; if ( DEBUG ) { console.log('currentTime-playtime='+difftime+' ( currentTime > playtime )='+( currentTime > playtime )); } if ( currentTime > playtime ) { // Is it past the timer? PlaySound = 1403; } } else { // Is this sound the last one played? // No, play the sound. SoundLastPlayedSound = SoundFile; SoundLastPlayedTime = currentTime; PlaySound = 1409; } // Is this sound the last one played? if ( DEBUG ) { console.log('PlaySound='+PlaySound+' SoundCount='+SoundCount+' !SoundMute='+!SoundMute+' SoundVolume='+SoundVolume); } if ( PlaySound && SoundCount && !SoundMute && SoundVolume !== '0' && SoundVolume !== 0 ) { // Should the sound be played? // Create the audio element text. let audio = "<audio id=\"soundtoplay\" onloadeddata=\"SoundLoaded = true;\" autoplay>\n\t<source src=\""+SoundFile+".mp3\" type=\"audio/mpeg\"><source src=\""+SoundFile+".wav\" type=\"audio/wav\">\n\t\n\t<img src=\""+HTTP_ROOT+"/images/sound_mute.png\" alt=\"Your browser does not support the audio element.\" title=\"Your browser does not support the audio element.\">\n</audio>";//SoundPlay("+soundfile+")"; //if ( DEBUG ) { console.info(PC+'audio.play['+SoundFile+']',CI); } // Put the text in spn_PlaySound. document.getElementById("spn_PlaySound").innerHTML = audio; // Define StartPlayback function for starting automatic playback. let StartPlayback = function() { //let StartPlaybackWorked = document.querySelector('#soundtoplay').play(); //return StartPlaybackWorked; return document.querySelector('#soundtoplay').play(); }; // In browsers that don’t yet support this functionality, playPromise won’t be defined. if ( audio !== undefined ) { // Is audio defined? if ( DEBUG ) { console.log('Attempt to play sound. autoplay='+document.getElementById('soundtoplay').autoplay); } // Yes, try starting automatic playback. let StartPlaybackWorked = null; StartPlaybackWorked = StartPlayback().then(function() { // Automatic playback started! SoundLastPlayedTime = currentTime; if ( DEBUG_SOUND || DEBUG ) { console.info(PC+TB+SoundFile+' played by='+by+'.',CI); } if ( DEBUG_SOUND || DEBUG ) { console.info(PC+TB+'SoundLoaded='+SoundLoaded+'.',CI); } SoundPlayButtonClicked(); // Hide the Sound play button. }).catch(function(error) { // Automatic playback failed. // Show a UI element to let the user manually start playback. console.log('catch function triggered. StartPlaybackWorked='+StartPlaybackWorked+' SoundLoaded='+SoundLoaded); SoundLastPlayedTime = 0; if ( document.getElementById('btn_SoundPlay') ) { document.getElementById('btn_SoundPlay').style.display = 'inline'; } if ( ( DEBUG_SOUND || DEBUG ) && SoundLoaded ) { console.info(PC+TB+SoundFile+' did not play by='+by+'.',CW); } }); //console.log('StartPlaybackWorked='+StartPlaybackWorked); } else { } // Is audio defined? } // Should the sound be played? SoundCount++; } } if ( DEBUG ) { console.groupEnd(); } } // END SoundPlay. // SoundPlayByName(sound, by) // Play the sound by name. Calls SoundPlay(). function SoundPlayByName(sound, by) { let DEBUGByName = DEBUG_OFF; if ( DEBUGByName ) { console.log('SoundPlayByName[sound='+sound+']'); } if ( typeof sound !== 'undefined' && sound ) { switch ( sound.charAt(0).toUpperCase() + sound.slice(1) ) { case 'Attention': SoundPlay(SoundAttention, 'SoundPlayByName '+by); break; case 'Available': SoundPlay(SoundAvailable, 'SoundPlayByName '+by); break; case 'Error': SoundPlay(SoundError, 'SoundPlayByName '+by); break; case 'Notice': SoundPlay(SoundNotice, 'SoundPlayByName '+by); break; case 'Ping': SoundPlay(SoundPing, 'SoundPlayByName '+by); break; case 'Warning': SoundPlay(SoundWarning, 'SoundPlayByName '+by); break; } } else { //SoundPlay(); } } // END SoundPlayByName. // SoundPlayByNameAuto(sound, refresh, by) // Play sound by name automatically every SoundTimer seconds. function SoundPlayByNameAuto(sound, refresh, by) { let DEBUG = DEBUG_OFF; if ( ( typeof refresh === 'undefined' ) || !refresh ) { refreshText = 'false'; } else { refreshText = 'true'; } if ( DEBUG ) { console.log('SoundPlayByNameAuto[sound='+sound+', refresh='+refreshText+', by='+by+'] SoundTimer='+SoundTimer); } if ( ( typeof sound !== 'undefined' ) && sound ) { SoundPlayByNameAutoSound = sound; } else { SoundPlayByNameAutoSound = false; } SoundPlayByNameAutoRefresh = refresh; // Remember the by. if ( typeof by !== 'undefined' ) { SoundPlayByNameAutoBy = by.split('|'); SoundPlayByNameAutoBy = SoundPlayByNameAutoBy[0]; } else { SoundPlayByNameAutoBy = 'undefined'; } SoundPlayByName(sound, 'SoundPlayByNameAuto '+by); let timer = 5000; // Re-call SoundPlayByNameAuto every 5 seconds. The sound will still only be played every SoundTimer seconds. let URI = HTTP_ROOT+'/Play/common/Refresh_LastAccess.php?refresh='+refreshText+'&by=SoundPlayByNameAuto[sound='+sound+',refresh='+refreshText+',by='+by+']SoundTimer='+SoundTimer; UpdateInclude(URI); //console.log(PC+'SoundPlayByNameAuto() clearInterval('+SoundPlayByNameAutoSetTimeout+'); AutoURI='+AutoURI,CE); clearInterval(SoundPlayByNameAutoSetTimeout); if ( DEBUG ) { console.log("SoundPlayByNameAutoSetTimeout = window.setTimeout(SoundPlayByNameAutoReturn,"+timer+");"); } SoundPlayByNameAutoSetTimeout = window.setTimeout(SoundPlayByNameAutoReturn,timer); } // END SoundPlayByNameAuto. // SoundPlayByNameAutoReturn() // Callback to re-call SoundPlayByNameAuto(). function SoundPlayByNameAutoReturn() { //console.log('SoundPlayByNameAutoReturn[sound='+SoundPlayByNameAutoSound+', refresh='+SoundPlayByNameAutoRefresh+', by='+SoundPlayByNameAutoBy+'] SoundTimer='+SoundTimer); SoundPlayByNameAutoReturnCount++; SoundPlayByNameAuto(SoundPlayByNameAutoSound, SoundPlayByNameAutoRefresh, SoundPlayByNameAutoBy+'|count='+SoundPlayByNameAutoReturnCount); } // END SoundPlayByNameAutoReturn. // SoundPlayButtonClicked(e) // Hide the 'Sound play' button after it has been clicked or a sound has been played. function SoundPlayButtonClicked(e) { let DEBUG = DEBUG_OFF; if ( typeof e !== 'undefined' ) { if ( DEBUG ) { console.group(PC+'SoundPlayButtonClicked[e.id='+e.id+']',CG); } ttHide(); } else { if ( DEBUG ) { console.group(PC+'SoundPlayButtonClicked[]',CG); } } if ( typeof e !== 'undefined' ) { e.style.display = 'none'; } else { if ( document.getElementById('btn_SoundPlay') ) { if ( DEBUG ) { console.log(PC+'btn_SoundPlay exists.',CI); } e = document.getElementById('btn_SoundPlay'); e.style.display='none'; } else { if ( DEBUG ) { console.log(PC+'btn_SoundPlay does not exist.',CW); } } } if ( DEBUG ) { console.log(PC+'GameInfo.SoundPlayButton='+GameInfo.SoundPlayButton,CI); } if ( document.getElementById('btn_SoundPlay') || GameInfo.SoundPlayButton ) { GameInfo.SoundPlayButton = 0; let URI = `${HTTP_ROOT}/Play/common/Set_Settings.php?task=SetSESSION&field1=game&field2=SoundPlayButton&value=false`; if ( DEBUG ) { console.log(PC+'UpdateInclude('+HTTP_PROTOCOL+'://'+SERVER_NAME+URI+'&DEBUG=true);',CD); } UpdateInclude(URI); } else { if ( DEBUG ) { console.log(PC+'SoundPlayButton=0',CL); } } if ( DEBUG ) { console.groupEnd(); } } // END SoundPlayButtonClicked. // SoundReset(); // Reset javascript sound setting to default values. function SoundReset() { let DEBUG = DEBUG_OFF; let soundId; soundId = 'id_Mute'; if ( document.getElementById(soundId) ) { let sounds = [ 'Mute', 'Attention', 'Available', 'Error', 'Notice', 'Ping', 'Warning' ]; let soundDiv; let soundFile; let soundRadioId; let soundSetting; for ( let i=0; i<sounds.length; i++ ) { let sound = sounds[i]; if ( DEBUG ) { console.log('sound='+sound); } switch ( sound ) { case 'Mute': if ( DEBUG ) { console.log('soundId='+soundId); } soundMute = document.getElementById(soundId).innerHTML; soundRadioId = 'id_Sound_'+sound+'_'+soundMute; if ( DEBUG ) { console.log('soundMute='+soundMute+' soundRadioId='+soundRadioId); } document.getElementById(soundRadioId).checked = true; let SoundMuteImage; let SoundMuteTooltip; if ( SoundMute ) { SoundMuteImage = HTTP_ROOT+'/images/sound_mute.png'; SoundMuteTooltip = 'Manage sound (currently: Mute all).'; } else { SoundMuteImage = HTTP_ROOT+'/images/sound_on.png'; SoundMuteTooltip = 'Manage sound (currently: All on).'; } if ( document.getElementById('id_Sound_Mute_Setting') ) { document.getElementById('id_Sound_Mute_Setting').innerHTML = '<abbr class="nodot" onMouseOver="ttShow(\''+SoundMuteTooltip+'\')" onMouseOut="ttHide();"><img src="'+SoundMuteImage+'" width="24" height="21" alt="Manage sound."></abbr>'; } break; case 'Attention': soundId = 'id_'+sound; if ( DEBUG ) { console.log('soundId='+soundId); } soundDiv = document.getElementById(soundId).innerHTML; soundDiv = soundDiv.split('|'); soundSetting = soundDiv[0]; soundFile = soundDiv[1]; if ( DEBUG ) { console.log('soundDiv='+soundDiv+' soundSetting='+soundSetting+' soundFile='+soundFile); } SoundAttention = soundFile; soundRadioId = 'id_Sound_'+sound+'_'+soundSetting; if ( DEBUG ) { console.log('soundRadioId='+soundRadioId); } document.getElementById(soundRadioId).checked = true; break; case 'Available': soundId = 'id_'+sound; if ( DEBUG ) { console.log('soundId='+soundId); } soundDiv = document.getElementById(soundId).innerHTML; soundDiv = soundDiv.split('|'); soundSetting = soundDiv[0]; soundFile = soundDiv[1]; if ( DEBUG ) { console.log('soundDiv='+soundDiv+' soundSetting='+soundSetting+' soundFile='+soundFile); } SoundAvailable = soundFile; soundRadioId = 'id_Sound_'+sound+'_'+soundSetting; if ( DEBUG ) { console.log('soundRadioId='+soundRadioId); } document.getElementById(soundRadioId).checked = true; break; case 'Error': soundId = 'id_'+sound; if ( DEBUG ) { console.log('soundId='+soundId); } soundDiv = document.getElementById(soundId).innerHTML; soundDiv = soundDiv.split('|'); soundSetting = soundDiv[0]; soundFile = soundDiv[1]; if ( DEBUG ) { console.log('soundDiv='+soundDiv+' soundSetting='+soundSetting+' soundFile='+soundFile); } SoundError = soundFile; soundRadioId = 'id_Sound_'+sound+'_'+soundSetting; if ( DEBUG ) { console.log('soundRadioId='+soundRadioId); } document.getElementById(soundRadioId).checked = true; break; case 'Notice': soundId = 'id_'+sound; if ( DEBUG ) { console.log('soundId='+soundId); } soundDiv = document.getElementById(soundId).innerHTML; soundDiv = soundDiv.split('|'); soundSetting = soundDiv[0]; soundFile = soundDiv[1]; if ( DEBUG ) { console.log('soundDiv='+soundDiv+' soundSetting='+soundSetting+' soundFile='+soundFile); } SoundNotice = soundFile; soundRadioId = 'id_Sound_'+sound+'_'+soundSetting; if ( DEBUG ) { console.log('soundRadioId='+soundRadioId); } document.getElementById(soundRadioId).checked = true; break; case 'Ping': soundId = 'id_'+sound; if ( DEBUG ) { console.log('soundId='+soundId); } soundDiv = document.getElementById(soundId).innerHTML; soundDiv = soundDiv.split('|'); soundSetting = soundDiv[0]; soundFile = soundDiv[1]; if ( DEBUG ) { console.log('soundDiv='+soundDiv+' soundSetting='+soundSetting+' soundFile='+soundFile); } SoundPing = soundFile; soundRadioId = 'id_Sound_'+sound+'_'+soundSetting; if ( DEBUG ) { console.log('soundRadioId='+soundRadioId); } document.getElementById(soundRadioId).checked = true; break; case 'Warning': soundId = 'id_'+sound; if ( DEBUG ) { console.log('soundId='+soundId); } soundDiv = document.getElementById(soundId).innerHTML; soundDiv = soundDiv.split('|'); soundSetting = soundDiv[0]; soundFile = soundDiv[1]; if ( DEBUG ) { console.log('soundDiv='+soundDiv+' soundSetting='+soundSetting+' soundFile='+soundFile); } SoundWarning = soundFile; soundRadioId = 'id_Sound_'+sound+'_'+soundSetting; if ( DEBUG ) { console.log('soundRadioId='+soundRadioId); } document.getElementById(soundRadioId).checked = true; break; } } } else { setTimeout(SoundReset,500); } } // END SoundReset. // SoundSave() // Save sound setting. function SoundSave(task) { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('SoundSave[task='+task+']'); } let sounds = [ 'Mute', 'Attention', 'Available', 'Error', 'Notice', 'Ping', 'Warning' ]; let query; let URI; switch ( task ) { // switch task. case 'Reset': document.getElementById('menu_SoundSetting_Return').innerHTML = task; if ( DEBUG ) { console.log('task='+task); } query = 'task='+task; URI = HTTP_ROOT+'/site/menu_SoundSettingSave.php?'+query; if ( DEBUG ) { console.log("UpdateInclude("+URI+", 'menu_SoundSetting_Return );"); } UpdateInclude(URI,'menu_SoundSetting_Return'); SoundReset(); break; case 'Save': document.getElementById('menu_SoundSetting_Return').innerHTML = task; let i; let sound; let setting; let radioName; let radios; let r; for ( i=0; i<sounds.length; i++ ) { // Loop thru radio buttons. sound = sounds[i]; setting = ''; radioName = 'Sound_'+sound; if ( DEBUG ) { console.log('radioName='+radioName); } radios = document.getElementsByName(radioName); for ( r=0; r<radios.length; r++) { // Loop thru radios. if (radios[r].checked) { setting = radios[r].value; break; } } // Loop thru radios. if ( DEBUG ) { console.log('task='+task+' sound='+sound+' setting='+setting); } query = 'task='+task+'&sound='+sound+'&setting='+setting; URI = HTTP_ROOT+'/site/menu_SoundSettingSave.php?'+query; if ( DEBUG ) { console.log("UpdateInclude("+URI+", 'menu_SoundSetting_Return );"); } UpdateInclude(URI,'menu_SoundSetting_Return'); } // Loop thru radio buttons. // Get Timer. let thisSelect = document.getElementById('id_Sound_Timer'); if ( DEBUG ) { console.log('thisSelect='+thisSelect); } let Timer = parseInt(thisSelect.options[thisSelect.selectedIndex].value); if ( DEBUG ) { console.log('Timer='+Timer); } query = 'task='+task+'&sound=Timer&setting='+Timer; URI = HTTP_ROOT+'/site/menu_SoundSettingSave.php?'+query; if ( DEBUG ) { console.log("UpdateInclude("+URI+", 'menu_SoundSetting_Return );"); } UpdateInclude(URI,'menu_SoundSetting_Return'); break; } // switch task. } // END SoundSave. // SoundSet(e) // Change a sound setting. function SoundSet(e) { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('SoundSet[e.id='+e.id+']'); } let temp = e.id.split('_'); if ( DEBUG ) { console.log('temp='+temp); } let sound = temp[2]; let setting; if ( typeof temp[3] !== 'undefined' ) { setting = temp[3]; } if ( DEBUG ) { console.log('sound='+sound+' setting='+setting); } switch ( sound ) { // switch sound. case 'Mute': SoundMute = parseInt(setting); let SoundMuteImage; let SoundMuteTooltip; if ( SoundMute === 1 ) { SoundMuteImage = HTTP_ROOT+'/images/sound_mute.png'; SoundMuteTooltip = 'Manage sound (currently: Mute all).'; } else { SoundMuteImage = HTTP_ROOT+'/images/sound_on.png'; SoundMuteTooltip = 'Manage sound (currently: All on).'; } if ( document.getElementById('id_Sound_Mute_Setting') ) { document.getElementById('id_Sound_Mute_Setting').innerHTML = '<abbr class="nodot" onMouseOver="ttShow(\''+SoundMuteTooltip+'\')" onMouseOut="ttHide();"><img src="'+SoundMuteImage+'" width="24" height="21" alt="Manage sound."></abbr>'; } break; case 'Attention': SoundAttention = '/sounds/attention'+setting+'.wav'; SoundPlay(SoundAttention, 'SoundSet'); break; case 'Available': SoundAvailable = '/sounds/available'+setting+'.wav'; SoundPlay(SoundAvailable, 'SoundSet'); break; case 'Error': SoundError = '/sounds/error'+setting+'.wav'; SoundPlay(SoundError, 'SoundSet'); break; case 'Notice': SoundNotice = '/sounds/notice'+setting+'.wav'; SoundPlay(SoundNotice, 'SoundSet'); break; case 'Ping': SoundPing = '/sounds/ping'+setting+'.wav'; SoundPlay(SoundPing, 'SoundSet'); break; case 'Warning': SoundWarning = '/sounds/warning'+setting+'.wav'; SoundPlay(SoundWarning, 'SoundSet'); break; case 'Timer': let thisSelect = document.getElementById('id_Sound_Timer'); setting = parseInt(thisSelect.options[thisSelect.selectedIndex].value); if ( DEBUG ) { console.log('setting='+setting); } SoundTimer = setting; break; } // switch sound. let task = 'Set'; document.getElementById('menu_SoundSetting_Return').innerHTML = task; let query = 'task='+task+'&sound='+sound+'&setting='+setting; let URI = HTTP_ROOT+'/site/menu_SoundSettingSave.php?'+query; if ( DEBUG ) { console.log("UpdateInclude("+URI+", 'menu_SoundSetting_Return );"); } UpdateInclude(URI,'menu_SoundSetting_Return'); } // END SoundSet. // starNoteDisplay(XY) // Rate or make notes on star. function starNoteDisplay(XY) { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('starNoteDisplay[XY='+XY+']'); } // Check for id_StarNote_XY_Event. let StarNote_XY; if ( document.getElementById('id_StarNote_XY_Event') ) { // Does id_StarNote_XY_Event exist? // Yes, check if XY is the same as id_StarNote_XY_Event. StarNote_XY = document.getElementById('id_StarNote_XY_Event').value; if ( DEBUG ) { console.log ('StarNote_XY='+StarNote_XY+' XY='+XY); } if ( XY === StarNote_XY ) { // Is this the Event XY? // Yes, display the id_StarNote_Event div and give the id_noteText_Event focus. ttHide(); document.getElementById('id_StarNote_Event').style.display = 'block'; document.getElementById('id_noteText_Event').focus(); if ( DEBUG ) { console.log(PC+'This is an event star note.',CF); } return; } else { // Is this the Event XY? if ( DEBUG ) { console.log(PC+'This is an map star note.',CT); } } // Is this the Event XY? } else { StarNote_XY = ''; if ( DEBUG ) { console.log(PC+'This is an map star note.',CT); } } // Does id_StarNote_XY_Event exist? let radios; let i; if ( typeof Mapstar[XY] !== 'undefined' ) { // Clear notePlayer radio checked. radios = document.getElementsByName('notePlayer'); for ( i = 0; i<radios.length; i++ ) { radios[i].checked = false; } // Clear noteRating radio checked. radios = document.getElementsByName('noteRating'); for ( i = 0; i<radios.length; i++ ) { radios[i].checked = false; } // Load dbStarNoteContents form values with playerstarnote. document.getElementById('id_StarNote_XY').value = XY; let locationText = Startype[Mapstar[XY].startypeId].ColorSpan+' '+Mapstar[XY].Name+'<span class="small"> ['+XY+']</span>'; if ( DEBUG ) { console.log('locationText='+locationText); } document.getElementById('id_StarNote_locationText').innerHTML = locationText; let note = Mapstar[XY].NoteText.replace(/<br>/g,"\n"); let player = Mapstar[XY].NotePlayer; let rating = Mapstar[XY].NoteRating; if ( DEBUG ) { console.log('XY='+XY+' note='+note+' player='+player+' rating='+rating); } if (document.getElementById('id_noteText')) { document.getElementById('id_noteText').value = note; } if ( player > 0 ) { if (document.getElementById('id_notePlayer'+player)) { document.getElementById('id_notePlayer'+player).checked = true; } } else { if(document.getElementById('id_notePlayer'+player)) { document.getElementById('id_notePlayer'+userId).checked = true; } } if ( rating >= 0 ) { if (document.getElementById('id_noteRating'+rating)) { document.getElementById('id_noteRating'+rating).checked = true; } } else { if (document.getElementById('id_playerstarNoRating')) { document.getElementById('id_playerstarNoRating').checked = true; } } if ( DEBUG ) { console.log(`${PC}moveDisplay[dbStarNoteContents','']`,CC); } moveDisplay('dbStarNoteContents',''); if (document.getElementById('id_noteText') ) { document.getElementById('id_noteText').focus(); } } else { console.info('Mapstar['+XY+'] is undefined'); } } // END starNoteDisplay. // StarNoteSave(e) // Save star note. function StarNoteSave(e) { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log(PC+'StarNoteSave[e.id='+e.id+' e.value='+e.value+']',CG); } ttHide(); // Check if this in an Event button. let IsEvent = ''; let StarNote_XY; if ( e.id.indexOf('_Event') === -1 ) { // Is this a map button? // Yes, check if this is . XY = document.getElementById('id_StarNote_XY').value; if ( DEBUG ) { console.log(PC+'This is an map star note.',CT); } } else { // Is this a map button? XY = document.getElementById('id_StarNote_XY_Event').value; if ( DEBUG ) { console.log(PC+'This is an event star note.',CS); } IsEvent = '_Event'; } // Is this a map button? if ( DEBUG ) { console.log(PC+'XY='+XY+' IsEvent='+IsEvent,CL); } // Get and save the star note. let i = 0; let note = ''; let query = ''; if ( DEBUG ) { console.log(PC+'e.value='+e.value,CL); } switch ( e.value.replace('S̲','S').replace('C̲','C') ) { // Switch on e.value. case 'Save': { // Get playerstarnote from form values. note = htmlSafe(document.getElementById('id_noteText'+IsEvent).value.trim()); if ( DEBUG ) { console.log(PC+'note='+note,CL); } let radios = document.getElementsByName('notePlayer'+IsEvent); if ( DEBUG ) { console.log('note='+note+' radios.length='+radios.length); } let player = 0; for ( i = 0; i<radios.length; i++) { // Loop thru notePlayer radio buttons. if ( DEBUG ) { console.log('radios['+i+'].name='+radios[i].name); } if (radios[i].checked) { player = radios[i].value; break; // Only one radio can be logically checked, don't check the rest. } } // Loop thru notePlayer radio buttons. if ( DEBUG ) { console.log('player='+player); } radios = document.getElementsByName('noteRating'+IsEvent); let rating = -1; for ( i = 0; i<radios.length; i++) { // Loop thru noteRating radio buttons. if ( DEBUG ) { console.log('radios['+i+'].name='+radios[i].name); } if (radios[i].checked) { rating = parseInt(radios[i].value); break; // only one radio can be logically checked, don't check the rest. } } // Loop thru noteRating radio buttons. if ( DEBUG ) { console.log('rating='+rating); } // Save in mapstar. Mapstar[XY].NoteText = note; Mapstar[XY].NotePlayer = player; Mapstar[XY].NoteRating = rating; Mapstar[XY].NoteTurn = playerTurn; let ratingSpan; switch ( rating ) { case -1: ratingSpan = ''; break; case 0: ratingSpan = ' <span style="background-color:'+MapColors.StarNameExploredBackground0+'; color:'+MapColors.StarNameExploredColor0+';">*</span>'; break; case 1: ratingSpan = ' <span style="background-color:'+MapColors.StarNameExploredBackground1+'; color:'+MapColors.StarNameExploredColor1+';">**</span>'; break; case 2: ratingSpan = ' <span style="background-color:'+MapColors.StarNameExploredBackground2+'; color:'+MapColors.StarNameExploredColor2+';">***</span>'; break; } if ( DEBUG ) { console.log('XY='+XY+' note='+note+' ratingSpan='+ratingSpan); } if ( document.getElementById('tt_Note_'+XY+IsEvent) ) { document.getElementById('tt_Note_'+XY+IsEvent).innerHTML = note; } if ( player === 0 ) { player = ''; } if ( document.getElementById('tt_Player_'+XY+IsEvent) ) { document.getElementById('tt_Player_'+XY+IsEvent).innerHTML = player; } if ( document.getElementById('tt_Rating_'+XY+IsEvent) ) { document.getElementById('tt_Rating_'+XY+IsEvent).innerHTML = ratingSpan; } if ( document.getElementById('tt_Notes_'+XY+IsEvent) ) { if ( note ) { // Is there a note? document.getElementById('tt_Notes_'+XY+IsEvent).style.display = 'table'; // Display the tt_Notes table. } else { document.getElementById('tt_Notes_'+XY+IsEvent).style.display = 'none'; // else hide it. } // Is there a note? } // Send note info to the server. if ( DEBUG ) { console.info('UPDATE the star note.'); } query = 'XY='+XY+'¬e='+encodeURIComponent(note)+'&player='+player+'&rating='+rating; if ( document.getElementById('canvasMapBase') ) { DrawMapFinish('StarNoteSave 2611'); } console.log('Mapstar['+XY+']='+JSON.stringify(Mapstar[XY])); if ( document.getElementById('id_noteText'+IsEvent) ) { console.log('id_noteText cleared'); document.getElementById('id_noteText'+IsEvent).value = note; } break; } case 'Clear': if ( document.getElementById('tt_Note_'+XY+IsEvent) ) { document.getElementById('tt_Note_'+XY+IsEvent).innerHTML = ''; } if ( document.getElementById('tt_Player_'+XY+IsEvent) ) { document.getElementById('tt_Player_'+XY+IsEvent).innerHTML = ''; } if ( document.getElementById('tt_Rating_'+XY+IsEvent) ) { document.getElementById('tt_Rating_'+XY+IsEvent).innerHTML = ''; } if ( document.getElementById('tt_Notes_'+XY+IsEvent) ) { document.getElementById('tt_Notes_'+XY+IsEvent).style.display = 'none'; } query = 'XY='+XY; Mapstar[XY].NoteText = ''; Mapstar[XY].NotePlayer = 0; Mapstar[XY].NoteRating = -1; console.log('Mapstar['+XY+']='+JSON.stringify(Mapstar[XY])); if ( document.getElementById('canvasMapBase') ) { DrawMapFinish('StarNoteSave 2626'); } if ( document.getElementById('id_noteText'+IsEvent) ) { console.log('id_noteText cleared'); document.getElementById('id_noteText'+IsEvent).value = ''; } break; } // Switch on e.value. let URI = HTTP_ROOT+'/Play/common/StarNotesSave.php?'+query; if ( DEBUG ) { console.log('UpdateInclude('+HTTP_PROTOCOL+'://'+SERVER_NAME+URI+'&DEBUG=true);'); } UpdateInclude(URI,'div_jsReturnData'); if ( !document.getElementById('id_StarNote_Event') ) { menuHide('StarNoteSave:1950'); } else { /** //**/if ( e.value === 'Close' ) { document.getElementById('id_StarNote_Event').style.display = 'none'; } } if ( IsEvent !== '' ) { // Is this an event star note? // Update star note screen text. if ( Mapstar[XY].NoteText !== '' || Mapstar[XY].NotePlayer !== 0 || Mapstar[XY].NoteRating !== -1 ) { // Is there a star note? // Yes, update to current text. document.getElementById('span_current_star_note').className = ''; document.getElementById('span_current_star_note').innerHTML = 'This is the current star note.'; document.getElementById('td_current_star_note').innerHTML = ''; } else { // Is there a star note? // No, update to no note. document.getElementById('span_current_star_note').className = 'info'; document.getElementById('span_current_star_note').innerHTML = 'There is currently no star note.'; document.getElementById('td_current_star_note').innerHTML = ''; } // Is there a star note? } // Is this an event star note? } // END StarNoteSave. // starValue() // Calculate and return the value of all planets at a star. function starValue() { let valueOfStar = 0; if ( PPXY[XY] ) { // Does this location have planets? for ( let i=0; i<PPXY[XY].length; i++ ) { // Loop thru planets. let pn = PPXY[XY][i]; if ( PP[pn].OW === userId || PP[pn].PO === userId ) { valueOfStar += PP[pn].Vnow; } else { valueOfStar += PP[pn].Vgame; } } // Loop thru planets. } // Does this location have planets? return valueOfStar; } // END starValue. // ttDisplay(evt) // Display map tooltip. function ttDisplay(evt,DEBUG=false) { // DEBUG = DEBUG_ON; evt = evt || window.event; // Get the event. if ( DEBUG ) { console.groupCollapsed(`${PC}ttDisplay[evt.tagret.id=${evt.target.id}] XY=${XY} GameId=${GameId}`,CG); } if ( GameId ) { ttinnerHTML = ''; if ( typeof PlayerEntryPoint === 'undefined' ) { PlayerEntryPoint = 0; } if ( MapEntrypointXYs.indexOf(XY) !== -1 ) { let EntryPointNumber = MapEntrypointXYs.indexOf(XY) + 1; if ( DEBUG ) { console.log('['+XY+'] entry '+EntryPointNumber+' PlayerEntryPoint='+PlayerEntryPoint); } if ( EntryPointNumber === PlayerEntryPoint ) { ttinnerHTML += 'This is your starting entry point.<br>'; } } ttinnerHTML = ttDisplay_onClick() + ttDisplay_Location(); if ( typeof Mapstar[XY] !== 'undefined' ) { ttinnerHTML += ttDisplay_Planets(); } ttinnerHTML += ttDisplay_InSpace() + ttDisplay_Fleets(); if ( typeof Mapstar[XY] !== 'undefined' ) { //console.log(PC+'Mapstar['+XY+']='+JSON.stringify(Mapstar[XY]),CI); ttinnerHTML += ttDisplay_Production() + ttDisplay_Events() + ttDisplay_Notes() + ttDisplay_TKO(XY); } if ( ttinnerHTML !== '[0000]') { if ( DEBUG ) { console.log(`${PC}ttShow[ttinnerHTML=${ttinnerHTML}]`,CC); } ttShow(ttinnerHTML,'',DEBUG); if ( DEBUG ) { console.log(`${PC}ttControl[evt,DEBUG]`,CC); } ttControl(evt,DEBUG); } else { if ( DEBUG ) { console.log(`${PC}ttShow skipped because ttinnerHTML=${ttinnerHTML}`,CW); } } } if ( DEBUG ) { console.groupEnd(); } } // END ttDisplay. // ttDisplay_Events() // Display game Events at XY. function ttDisplay_Events() { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('ttDisplay_Events[] XY='+XY+''); } if ( DEBUG ) { console.log('playerScreen='+playerScreen); } ttContent_Events = ''; if ( typeof Events !== 'undefined' ) { let uId; let uText; for ( let u=0; u<UserIdsEvent.length; u++ ) { // Loop thtu UserIdsEvent. uId = UserIdsEvent[u]; if ( typeof Events[uId] !== 'undefined' ) { if ( typeof Events[uId][XY] !== 'undefined' ) { // Are there Events? if ( UserIdsEvent.length > 1 ) { uText = ' <span class="normal">for</span> '+PlayerColorNames[uId]; } else { uText = ''; } ttContent_Events += '<table class="ttTable">'; ttContent_Events += "\n\t"+'<thead><tr><th class="left" colspan="2">Events'+uText+'</th></tr><tr><td class="center">T#</td><td class="left">Event</td></tr></thead>'; ttContent_Events += "\n\t"+'<tbody>'; let eventColorAction; let eventsToShow = Math.min(Events[uId][XY].length,ttMaxEventsToShow); let TRnow; let TRprevious = 0; let TRtext; for ( let i=0; i<eventsToShow; i++ ) { if ( Events[uId][XY][i].hidden === 0 ) { switch ( Events[uId][XY][i].action ) { // Class attention. case 'Take Over': eventColorAction = '<span class="attention">'+Events[uId][XY][i].action+'</span>'; break; // Class errortext. case 'Fleet Destroyed': case 'Fleet Lost': case 'Lost Contact': case 'Out of Range Losses': eventColorAction = '<span class="errortext">'+Events[uId][XY][i].action+'</span>'; break; // Class info. case 'Explore': eventColorAction = '<span class="info">'+Events[uId][XY][i].action+'</span>'; break; // Class warntext. case 'Adjust Defense': case 'Bombardment': case 'Combat': case 'Initial Defense': case 'Movement Losses': eventColorAction = '<span class="warntext">'+Events[uId][XY][i].action+'</span>'; break; //case '': default: eventColorAction = Events[uId][XY][i].action; break; } TRnow = Events[uId][XY][i].TR;//ttTR(Events[uId][XY][i].Turn); let eventResult = Events[uId][XY][i].result; if ( TRnow !== TRprevious ) { TRprevious = TRnow; TRtext = TRnow; } else { TRtext = ''; } ttContent_Events += "\n\t"+'<tr><td class="right">'+TRtext+'</td><td>'+eventColorAction+eventResult+'</td></tr>'; } } let moreEvents = Events[uId][XY].length - eventsToShow; let moreEventsPlural; if ( moreEvents ) { if ( moreEvents > 1 ) { moreEventsPlural = 's'; } else { moreEventsPlural = ''; } ttContent_Events += "\n\t"+'<tr><td></td><td class="info">'+moreEvents+' more event'+moreEventsPlural+' ...</td></tr>'; } ttContent_Events += "\n\t"+'</tbody>'; ttContent_Events += "\n"+'</table>'; } // Are there Events? } } // Loop thtu UserIdsEvent. } return ttContent_Events; } // END ttDisplay_Events. // ttDisplay_Fleets() // Display fleets at XY. function ttDisplay_Fleets() { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('ttDisplay_Fleets[] XY='+XY+''); } //if ( DEBUG ) console.log('playerScreen='+playerScreen); let ttContent_Fleets = ''; let ttContent_FleetsPlayer = ''; let ttContent_FleetsEnemy = ''; let ttContent_Fleets_Previous = ''; // Used to stop multiple ? fleets from same player. let tuId; let FleetCount = 0; if ( typeof PlayerfleetByXY !== 'undefined' ) { // Are there fleets? if ( typeof PlayerfleetByXY[XY] !== 'undefined' && PlayerfleetByXY[XY].length ) { // Are there fleets at this XY? if ( DEBUG ) { console.info('PlayerfleetByXY['+XY+']='+PlayerfleetByXY[XY]); } let PlayerFleetCountAtThisXY = 0; let PlayerFleetsWithoutDestinationAtThisXY = 0; for ( let FleetIndex=0; FleetIndex<PlayerfleetByXY[XY].length; FleetIndex++ ) { // Loop thru fleets at this XY. let UN = PlayerfleetByXY[XY][FleetIndex]; let fleetName = PF[UN].Name; FleetCount++; if ( DEBUG ) { console.log(PlayerNames[PF[UN].userId]+' fleet '+PF[UN].Name+' fleetName='+fleetName); } if ( DEBUG ) { clog('271 PF['+fleetName+']',PF[UN],''); } // Add fleet name. if ( PF[UN].userId === userId ) { // Is this a player fleet? // Yes, Player fleet. PlayerFleetCountAtThisXY++; if ( PF[UN].dXY === '' ) { PlayerFleetsWithoutDestinationAtThisXY++; } if ( DEBUG ) { console.log('PF['+fleetName+'].userId == '+userId); } ttContent_FleetsPlayer += "\n\t"+'<tr><td class="right">'; ttContent_FleetsPlayer += PF[UN].Name+')</td>'; // Add contents. if ( DEBUG ) { console.log("typeof PFU["+fleetName+"] !== 'undefined'=",(typeof PFU[UN] !== 'undefined')); } let fleetContents = []; if ( typeof PFU[UN] !== 'undefined' ) { // Does this fleet have units? if ( DEBUG ) { console.log('TechunitIds='+TechunitIds+' TechunitIds.length='+TechunitIds.length); } for ( t=0; t<TechunitIds.length; t++ ) { tuId = TechunitIds[t]; if ( DEBUG ) { console.log("typeof PFU['+fleetName+']['+tuId+'] !== 'undefined'=",(typeof PFU[UN][tuId] !== 'undefined')); } if ( typeof PFU[UN][tuId] !== 'undefined' ) { // Loop thru fleet units. //console.log('tuId='+tuId); if ( DEBUG ) { console.log('PFU['+fleetName+']['+tuId+']='+PFU[UN][tuId]); } if ( PFU[UN][tuId] > 0 ) { let unitText = PFU[UN][tuId]+' '+Techunit[tuId].Name; if ( PFU[UN][tuId] > 1 ) { unitText += 's'; } fleetContents.push(unitText); } } // Loop thru fleet units. } if ( fleetContents.length === 0 ) { fleetContents = ['<span class="warntext">empty</span>']; } } else { fleetContents = ['<span class="warntext">empty</span>']; } // Does this fleet have units? ttContent_FleetsPlayer += '<td>'; if ( fleetContents.length ) { let prefix = ''; let fleetContentsEnd = fleetContents.length - 1; if ( fleetContentsEnd === 0 ) { fleetContentsEnd = -1; } for ( let c=0; c<fleetContents.length; c++ ) { ttContent_FleetsPlayer += prefix; if ( c === fleetContentsEnd ) { ttContent_FleetsPlayer += 'and '; } ttContent_FleetsPlayer += fleetContents[c]; if ( fleetContentsEnd > 1 ) { prefix = ', '; } else { prefix = ' '; } } } ttContent_FleetsPlayer += '</td><td>'; // Add destination. if ( PF[UN].dTurns > 0 ) { if ( PF[UN].dNote.indexOf('warp') === -1 ) { // Is this regular movement? ttContent_FleetsPlayer += 'moves to '+PF[UN].dName+' in '+PF[UN].dTurns+' turn'; if ( PF[UN].dTurns > 1 ) { ttContent_FleetsPlayer += 's'; } } else { // Is this regular movement? ttContent_FleetsPlayer += '<span class="warntext">warps</span> to '+PF[UN].dName; } // Is this regular movement? } else { // Check for Run. if ( PF[UN].Action.indexOf('Run') === -1 ) { // Is the fleet not running. if ( PF[UN].dTurns === 0 ) { ttContent_FleetsPlayer += '<span class="info">Just arrived</span>'; } } else { // Is the fleet not running. // The fleet is running. let runXY = PF[UN].Action.substr(3); ttContent_FleetsPlayer += '<span class="info">Run from combat at '; if ( typeof Mapstar[runXY] !== 'undefined' ) { ttContent_FleetsPlayer += Mapstar[runXY].Name; } else { ttContent_FleetsPlayer += runXY; } ttContent_FleetsPlayer += '.</span>'; } // Is the fleet not running. } // Add Bomb. if ( DEBUG ) { console.log('PF['+UN+'].Bomb='+PF[UN].Bomb); } if ( PF[UN].Bomb === 1 ) { ttContent_FleetsPlayer += ' <span class="isOn">Bomb</span>'; } ttContent_FleetsPlayer += '</td></tr>'; } else { // Is this a player fleet? // No, Enemy fleet. if ( DEBUG ) { console.info('PF['+fleetName+'].userId != '+userId+' IsPlayerFleetHere='+IsPlayerFleetHere(XY,'ttDisplay_Fleets')+' IsPlayerHere='+IsPlayerHere(XY,'ttDisplay_Fleets')); } if ( ( typeof Mapstar[XY] !== 'undefined' ) && ( IsPlayerFleetHere(XY,'ttDisplay_Fleets') || IsPlayerHere(XY,'ttDisplay_Fleets') ) ) { // Is this a star hex and is the player here? if ( PlayerStatus[PF[UN].userId].Turn <= playerTurn || PF[UN].dTurns === -1 ) { // Is the player NOT in the future or was the fleet already here? // Count playerfleetunit total ships. let playerfleetunitTotal = 0; if ( typeof PFU[UN] !== 'undefined' ) { // Does this fleet have units? for ( t=0; t<TechunitIds.length; t++ ) { // Loop thru ships. tuId = TechunitIds[t]; if ( typeof PFU[UN][tuId] !== 'undefined' ) { // Loop thru fleet units. //console.log('tuId='+tuId); //console.log('PFU['+fleetName+']['+tuId+']='+PFU[UN][tuId]); if ( PFU[UN][tuId] > 0 ) { playerfleetunitTotal += PFU[UN][tuId]; } } // Loop thru fleet units. } // Loop thru ships. } // Does this fleet have units? //playerfleetunitTotal = 1 // UNCOMMENT to force view of empty enemy fleets. if ( playerfleetunitTotal ) { // Does the enemy fleet have units? ttContent_Fleets_Current = "\n\t"+'<tr><td>'; ttContent_Fleets_Current += '<span style="color:'+PlayerColors[PF[UN].userId].Color+'; background-color:'+PlayerColors[PF[UN].userId].Background+';">?)</td><td colspan="2"style="color:'+PlayerColors[PF[UN].userId].Color+'; background-color:'+PlayerColors[PF[UN].userId].Background+';">'+PlayerNames[PF[UN].userId]+'</span>'; if ( PF[UN].dTurns > 0 ) { ttContent_Fleets_Current += ' <span class="info">Glancing thru outer edge of the system.</span>'; } ttContent_Fleets_Current += '</td></tr>'; if ( ttContent_Fleets_Current !== ttContent_Fleets_Previous ) { ttContent_FleetsEnemy += ttContent_Fleets_Current; } ttContent_Fleets_Previous = ttContent_Fleets_Current; } // Does the enemy fleet have units? } // Is the player NOT in the future or was the fleet already here? } // Is this a star hex and is the player here? } // Is this a player fleet? } // Loop thru fleets at this XY. if ( DEBUG ) { console.log('ttContent_FleetsPlayer='+ttContent_FleetsPlayer+' ttContent_FleetsEnemy='+ttContent_FleetsEnemy); } if ( ttContent_FleetsPlayer || ttContent_FleetsEnemy ) { ttContent_Fleets += '<table class="ttTable">'; ttContent_Fleets += "\n\t"+'<thead><tr><th class="left" colspan="3">Fleets</th></tr></thead>'; ttContent_Fleets += "\n\t"+'<tbody>'; ttContent_Fleets += ttContent_FleetsPlayer + ttContent_FleetsEnemy; if ( !Mapstar[XY] && PlayerFleetCountAtThisXY && !PlayerFleetsWithoutDestinationAtThisXY && Techlimit.movement && Techlimit.movement.change && Techlimit.movement.change === 'star' ) { ttContent_Fleets += "\n\t"+'<tr><td colspan="3" class="warntext">Fleet'; if ( PlayerFleetCountAtThisXY > 1 ) { ttContent_Fleets += 's'; } ttContent_Fleets += ' cannot change destination.</td></tr>'; } ttContent_Fleets += "\n\t"+'</tbody>'; ttContent_Fleets += "\n"+'</table>';//+Techlimit.movement.change; } } else { // Are there fleets at this XY? if ( DEBUG ) { console.info('There are no fleets at '+XY+'.'); } } // Are there fleets at this XY? } else { if ( DEBUG ) { console.info('There are no fleets.'); } } // Are there fleets? if ( DEBUG ) { console.log('ttContent_Fleets='+ttContent_Fleets); } return ttContent_Fleets; } // END ttDisplay_Fleets. // ttDisplay_InSpace() // Display ships and orbital bases at XY. function ttDisplay_InSpace() { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('ttDisplay_InSpace[] XY='+XY+''); } //if ( DEBUG ) console.log('playerScreen='+playerScreen); let ttContent_InSpace = ''; if ( playerorbitalbaseXYs.indexOf(XY) !== -1 || playershipXYs.indexOf(XY) !== -1 ) { // Are there ships or orbital bases here? let UXY; let tuId; let unitText; let InSpaceContents = []; let t; if ( playershipXYs.indexOf(XY) !== -1 ) { // Are there ships here? UXY = userId+'_'+XY; for ( t=0; t<TechunitIds.length; t++ ) { // Loop thru tech units. tuId = TechunitIds[t]; if ( typeof PSU[UXY] !== 'undefined' && typeof PSU[UXY][tuId] !== 'undefined' && PSU[UXY][tuId] > 0 ) { // Is this unit here? unitText = PSU[UXY][tuId] + ' ' + Techunit[tuId].Name; if ( PSU[UXY][tuId] > 1 ) { unitText += 's'; } InSpaceContents.push(unitText); } // Is this unit here? } // Loop thru tech units. } // Are there ships here? if ( playerorbitalbaseXYs.indexOf(XY) !== -1 ) { // Are there orbital bases here? UXY = userId+'_'+XY; for ( t=0; t<TechunitIds.length; t++ ) { // Loop thru tech units. tuId = TechunitIds[t]; if ( ( typeof POU[UXY] !== 'undefined' ) && ( typeof POU[UXY][tuId] !== 'undefined' ) && POU[UXY][tuId] > 0 ) { // Is this unit here? unitText = POU[UXY][tuId] + ' ' + Techunit[tuId].Name; if ( POU[UXY][tuId] > 1 ) { unitText += 's'; } InSpaceContents.push(unitText); } // Is this unit here? } // Loop thru tech units. } // Are there orbital bases here? 0525 //console.log('playerAction='+playerAction+' document.getElementById(\'id_CTsInSpace_'+XY+'\')='+document.getElementById('id_CTsInSpace_'+XY)+' XY='+XY); if ( playerAction === 'Production' && document.getElementById('id_CTsInSpace_'+XY) && document.getElementById('id_CTsInSpace_'+XY).value > 0 ) { // Are there CTs placed inspace? unitText = document.getElementById('id_CTsInSpace_'+XY).value+' '+Techunit[POPtransport_tuId].Name; if ( document.getElementById('id_CTsInSpace_'+XY).value > 1 ) { unitText += 's'; } InSpaceContents.push('<span class="production">'+unitText+' placed in space.</span>'); } // Are there CTs placed inspace? if ( InSpaceContents.length ) { let InSpaceContent = ''; let prefix = ''; let InSpaceContentsEnd = InSpaceContents.length - 1; if ( InSpaceContentsEnd === 0 ) { InSpaceContentsEnd = -1; } for ( let c=0; c<InSpaceContents.length; c++ ) { InSpaceContent += prefix; if ( c === InSpaceContentsEnd ) { InSpaceContent += 'and '; } InSpaceContent += InSpaceContents[c]; if ( InSpaceContentsEnd > 1 ) { prefix = ', '; } else { prefix = ' '; } } ttContent_InSpace += '<table class="ttTable">'; ttContent_InSpace += "\n\t"+'<thead><tr><th class="left">InSpace</th></tr></thead>'; ttContent_InSpace += "\n\t"+'<tbody>'; ttContent_InSpace += "\n\t"+'<tr><td>'+InSpaceContent+'</td></tr>'; ttContent_InSpace += "\n\t"+'</tbody>'; ttContent_InSpace += "\n"+'</table>'; } } // Are there ships or orbital bases here? if ( DEBUG ) { console.log('ttContent_InSpace='+ttContent_InSpace); } return ttContent_InSpace; } // END ttDisplay_InSpace. // ttDisplay_Location() // Display star name if at star and/or hex location. function ttDisplay_Location() { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('ttDisplay_Location[] XY='+XY+''); } if ( DEBUG ) { console.log('playerScreen='+playerScreen); } ttContent_Location = ''; if ( typeof Mapstar[XY] !== 'undefined' ) { // Is this a star? // At star. let DustText = ''; if ( MapDustHexXYs.indexOf(XY) !== -1 ) { DustText = ' in dust cloud'; } ttContent_Location += '<b>'+Startype[Mapstar[XY].startypeId].ColorSpan+' '+Mapstar[XY].Name+'</b> ['+XY; if ( XY === homeSystem ) { ttContent_Location += ' home system'; } ttContent_Location +=']'+DustText; } else { // Is this a star? if ( MapDustHexXYs.indexOf(XY) !== -1 ) { // Is this a dust hex? ttContent_Location += '['+XY+'] dust cloud'; // Dust hex. } else { // Is this a dust hex? ttContent_Location += '['+XY+']'; // Space hex. } // Is this a dust hex } // Is this a star? let starValueAtLocation = starValue(); if ( starValueAtLocation ) { ttContent_Location += ' = '+starValueAtLocation; } if ( DEBUG ) { console.log('ttContent_Location='+ttContent_Location); } return ttContent_Location; } // END ttDisplay_Location. // ttDisplay_Notes() // Display Notes about XY. function ttDisplay_Notes() { let DEBUG_Notes = DEBUG_OFF; if ( DEBUG_Notes ) { console.log('ttDisplay_Notes[] XY='+XY+''); } if ( DEBUG_Notes ) { console.log('playerScreen='+playerScreen); } ttContent_Notes = ''; if ( Mapstar[XY] && Mapstar[XY].NoteText !== '' ) { // Is this a star? ttContent_Notes += '<table class="ttTable">'; ttContent_Notes += "\n\t"+'<thead><tr><th class="left">Notes</th><td>TR: '+ttTR(Mapstar[XY].NoteTurn)+'</tr></thead>'; ttContent_Notes += "\n\t"+'<tbody>'; if ( Mapstar[XY].NotePlayer !==0 && Mapstar[XY].NotePlayer !== userId ) { ttContent_Notes += "\n\t"+'<tr><td colspan="2">'+PlayerColorNames[Mapstar[XY].NotePlayer]+'</td></tr>'; } ttContent_Notes += "\n\t"+'<tr><td colspan="2">'+Mapstar[XY].NoteText+'</td></tr>'; ttContent_Notes += "\n\t"+'</tbody>'; ttContent_Notes += "\n"+'</table>'; } return ttContent_Notes; } // END ttDisplay_Notes. // ttDisplay_Planets() // Display known planets at XY. function ttDisplay_Planets() { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.group(PC+'ttDisplay_Planets[] XY=['+XY+'] playerScreen=['+playerScreen+']',CG); } ttContent_Planets = ''; let ProductionChangeClass; if ( typeof Mapstar[XY] !== 'undefined' ) { // Is this a star? if ( DEBUG ) { console.info(PC+Mapstar[XY].Name+' Mapstar['+XY+'].PNs='+Mapstar[XY].PNs+' .Turn='+Mapstar[XY].Turn,CI); } if ( Mapstar[XY].Turn !== -1 ) { // Has this star been explored? // This star has been explored. if ( DEBUG ) { console.info(PC+'This star has been explored.',CI); } // Show planet info if: // 1. There are planets ( typeof Mapstar[XY].PNs !== 'undefined' ) && Mapstar[XY].PNs.length > 0. // 2. There are PP[pn] entries ( typeof PP[Mapstar[XY].PNs[0]] !== 'undefined' ). // 3. The playerAction is not 'Spend Initial RPs' or the player previewed their home system ( playerAction != 'Spend Initial RPs' || GameInfo.previewHome ). if ( ( typeof Mapstar[XY].PNs !== 'undefined' ) && Mapstar[XY].PNs.length > 0 && ( typeof PP[Mapstar[XY].PNs[0]] !== 'undefined' ) && ( playerAction !== 'Spend Initial RPs' || GameInfo.previewHome ) ) { // Does this star have viewable planets? // This star has viewable planets. if ( DEBUG ) { console.info(PC+'This star has viewable planets. Mapstar['+XY+'].PNs='+Mapstar[XY].PNs,CI); } let p; // Index for looping thru planets. let pn = Mapstar[XY].PNs[0]; // Get EnemyHasSpaceCombatUnits. // Display last explored if not current. if ( PP[pn].Turn !== playerTurn ) { ttContent_Planets += '<br><span class="info">Last explored on turn '+ttTR(PP[pn].Turn)+'.</span>'; } ttContent_Planets += '<table class="ttTable">'; ttContent_Planets += "\n\t"+'<thead><tr><th class="left" colspan="6">Planets</th></tr></thead>'; ttContent_Planets += "\n\t"+'<tbody>'; let EnemyHasSpaceCombatUnits = false; for ( p=0; p<Mapstar[XY].PNs.length; p++ ) { // Loop thru planets. pn = Mapstar[XY].PNs[p]; if ( PP[pn].OW !== userId && ttEnemyHasSpaceCombatUnits(PP[pn].OW, PP[pn].XY) ) { EnemyHasSpaceCombatUnits = true; } } if ( DEBUG ) { console.log(PC+'EnemyHasSpaceCombatUnits='+EnemyHasSpaceCombatUnits,CL); } if ( DEBUG ) { console.log(PC+'Mapstar['+XY+'].PNs='+Mapstar[XY].PNs,CI); } for ( p=0; p<Mapstar[XY].PNs.length; p++ ) { // Loop thru planets. let LostContact = false; pn = Mapstar[XY].PNs[p]; let pd = p+1; let pp = PP[pn]; if ( DEBUG ) { console.groupCollapsed(PC+ttPd(pn)+' pn='+pn+' PP['+pn+'].OW='+pp.OW+' .LC='+pp.LC,CG); } if ( DEBUG ) { console.log(PC+'PP['+pn+']='+JSON.stringify(pp),CI); } ttContent_Planets += "\n\t"+'<tr>'; // BEGIN tr. let playerIsHere = IsPlayerHere(XY,'ttDisplay_Planets 2570'); // Check if player is here. if ( DEBUG ) { console.log(PC+'playerIsHere='+playerIsHere,CL); } // Show planet number. ttContent_Planets += '<td class="narrow right"'; if ( playerIsHere && pp.OW !== -1 ) { // Is the player here and the planet owned by someone? // && pp.LC === 0 ttContent_Planets += ' style="background-color:'+PlayerColors[pp.OW].Background+'; color:'+PlayerColors[pp.OW].Color+';"'; // Show planet number in owner color. } // Is the player here and the planet owned by someone? ttContent_Planets += '>'+pd+')'+'</td>'; if ( playerIsHere ) { // Is the player here? if ( DEBUG ) { console.info(PC+'The player is here at planet '+pn+'.',CI); } if ( pp.OW === userId ) { // Is this planet owned by the player? // This planet is owned by the user. if ( DEBUG ) { console.info(PC+'The planet is owned by the player.',CI); } if ( pp.LC === 0 && pp.Note.indexOf('LostContact') === -1 && pp.Note.indexOf('TakeOver') === -1 ) { // Is this planet currently owned by the user? // This planet is currently owned by the user. Show playerplanet info with content. if ( DEBUG ) { console.info(PC+'The player has not Lost Contact with the planet.',CI); } if ( DEBUG ) { console.info(PC+'Display planet contents.',CD); } ttContent_Planets += '<td class="narrow">'; ProductionChangeClass = ''; if ( ttPlanetIsOriginal(pn) ) { // Is the planet original? if ( DEBUG ) { console.info(PC+'The planet is original.',CI); } if ( ttPlanetIsPlayer(pn) ) { // Is the planet unchanged by production? if ( DEBUG ) { console.info(PC+'The planet is unchanged by production.',CI); } // Show player. if ( DEBUG ) { console.info(PC+'Show player planet contents.',CD); } ttContent_Planets += Planettype[pp.TYPEp].Code + pp.HABp + PlanetNMsuffix[pp.NMp]; } else { // Is the planet unchanged by production? if ( DEBUG ) { console.info(PC+'The planet was changed by production.',CI); } // Show player changed and set to show production. if ( DEBUG ) { console.info(PC+'Show player planet changed by production.',CD); } ttContent_Planets += '<span class="planetChange">'; ttContent_Planets += Planettype[pp.TYPEp].Code + pp.HABp + PlanetNMsuffix[pp.NMp]; ttContent_Planets += '</span> '; ProductionChangeClass = 'production'; } // Is the planet unchanged by production? } else { // Is the planet original? if ( DEBUG ) { console.info(PC+'The planet is NOT original.',CI); } // Show original changed. ttContent_Planets += '<span class="planetChange">'; ttContent_Planets += Planettype[pp.TYPEo].Code + pp.HABo + PlanetNMsuffix[pp.NMo]; ttContent_Planets += '</span> '; if ( ttPlanetIsPlayer(pn) ) { // Is the planet unchanged by production? if ( DEBUG ) { console.info(PC+'The planet is unchanged by production.',CI); } // Show player. if ( DEBUG ) { console.info(PC+'Show player planet contents.',CD); } ttContent_Planets += Planettype[pp.TYPEp].Code + pp.HABp + PlanetNMsuffix[pp.NMp]; } else { // Is the planet unchanged by production? if ( DEBUG ) { console.info(PC+'The planet was changed by production.',CI); } // Show player changed and set to show production. if ( DEBUG ) { console.info(PC+'Show player planet changed by production.',CD); } ttContent_Planets += '<span class="planetChange">'; ttContent_Planets += Planettype[pp.TYPEp].Code + pp.HABp + PlanetNMsuffix[pp.NMp]; ttContent_Planets += '</span> '; ProductionChangeClass = 'production'; } // Is the planet unchanged by production? } let VAL; if ( DEBUG ) { console.info(PC+'ProductionChangeClass="'+ProductionChangeClass+'" PP['+pn+'].VALp='+pp.VALp+' PP['+pn+'].VALr='+pp.VALr,CI); } if ( ProductionChangeClass === '' ) { VAL = pp.VALp; } else { // Show production. ttContent_Planets += '<span class="production">'; ttContent_Planets += Planettype[pp.TYPEr].Code + pp.HABr + PlanetNMsuffix[pp.NMr]; ttContent_Planets += '</span> '; VAL = pp.VALr; } ttContent_Planets += '</td>'; // Add planet contents and value. ttContent_Planets += '<td>'+ttDisplay_Planets_Contents(pn)+'</td>'; //ttContent_Planets += '<td class="narrow'+ProductionChangeClass+'">=</td>'; ttContent_Planets += '<td class="narrow'+ProductionChangeClass+'">v'+VAL+'</td>'; } else { // This planet was previously owned by the user. Show 'Lost Contact'. if ( DEBUG ) { console.info(PC+'The user has Lost Contact with the planet.',CI); } ttContent_Planets += '<td class="narrow">'+Planettype[pp.TYPEr].Code+pp.HABr+PlanetNMsuffix[pp.NMr]+'</td>'; ttContent_Planets += '<td class="errortext">Lost Contact</td>'; //ttContent_Planets += '<td class="narrow">=</td>'; ttContent_Planets += '<td class="narrow">v'+pp.VALp+'</td>'; } } else if ( pp.OW !== -1 ) { // Is this planet owned by another player? // This planet is owned by another user. if ( DEBUG ) { console.info(PC+'This planet is owned by another player.',CI); } if ( pp.LC === 0 && pp.Note.indexOf('Lost Contact') === -1 ) { // Does the owner still have contact? if ( DEBUG ) { console.info(PC+'This owner still has contact.',CI); } // This planet is currently owned by another user. Show playerplanet info with GBs or full content. ttContent_Planets += '<td class="narrow">'+Planettype[pp.TYPEr].Code+pp.HABr; if ( pp.NMr ) { ttContent_Planets += PlanetNMsuffix[pp.NMr]; } ttContent_Planets += '</td>'; if ( EnemyHasSpaceCombatUnits ) { if ( DEBUG ) { console.info(PC+'The enemy has space combat units.',CI); } if ( DEBUG ) { console.info(PC+'Do not show playerplanet info.',CD); } ttContent_Planets += '<td></td>'; } else { if ( DEBUG ) { console.info(PC+'The enemy does NOT have space combat units.',CI); } if ( DEBUG ) { console.info(PC+'Show playerplanet info with GBs or full content.',CD); } ttContent_Planets += '<td>'+ttDisplay_Planets_Contents(pn,pp.OW)+'</td>'; } //ttContent_Planets += '<td class="narrow">=</td>'; ttContent_Planets += '<td class="narrow">v'+pp.VALp+'</td>'; } else { // Does the owner still have contact? if ( DEBUG ) { console.info(PC+'This owner does NOT have contact.',CI); } if ( DEBUG ) { console.info(PC+'Show prod info.',CD); } ttContent_Planets += '<td class="narrow">'+Planettype[pp.TYPEr].Code+pp.HABr+PlanetNMsuffix[pp.NMr]+'</td>'; // Check if player is the TKO player. if ( pp.Note.indexOf('LostContact:userId='+userId) !== -1 || pp.Note.indexOf('TakeOver:userId='+userId) !== -1 || pp.Note.indexOf('Production:userId='+userId) !== -1 ) { // Is the player the TKO player? if ( DEBUG ) { console.info(PC+'The player is the TKO player.',CI); } if ( DEBUG ) { console.info(PC+'Show planet contents with TKO or PRD.',CD); } // Show the contents. ttContent_Planets += '<td>'+ttDisplay_Planets_Contents(pn,pp.OW); if ( pp.Note.indexOf('LostContact:userId='+userId) !== -1 || pp.Note.indexOf('TakeOver:userId='+userId) !== -1 ) { ttContent_Planets += ' <span class="info">TKO</span>'; } if ( pp.Note.indexOf('Production:userId='+userId) !== -1 ) { ttContent_Planets += ' <span class="production">PRD</span>'; } ttContent_Planets += '</td>'; } else { // Is the player the TKO player? if ( DEBUG ) { console.info(PC+'The player NOT the TKO player.',CI); } if ( DEBUG ) { console.info(PC+'Show no contents.',CD); } ttContent_Planets += '<td></td>'; } // Is the player the TKO player? //ttContent_Planets += '<td class="narrow">=</td>'; ttContent_Planets += '<td class="narrow">v'+pp.VALp+'</td>'; } // Does the owner still have contact? } else { // Is this planet owned by another player? // This planet is not owned by any player. if ( DEBUG ) { console.info(PC+'This planet is not owned by any player.',CI); } if ( pp.Note.indexOf('Obliterated') !== -1 ) { // Is there an obliterated note? // There is an obliterated note. Show playerplanet info. if ( DEBUG ) { console.log(TB+'There is an obliterated note. Show playerplanet info without content.'); } ttContent_Planets += '<td class="narrow">'+Planettype[pp.TYPEr].Code+pp.HABr+PlanetNMsuffix[pp.NMr]+'</td>'; ttContent_Planets += '<td>'; if ( playerAction === 'Production' && pp.COLnext ) { ttContent_Planets += ttDisplay_Planets_Contents(pn,pp.OW); } if ( pp.Note !== '' ) { ttContent_Planets += ' '+pp.Note; } ttContent_Planets += '</td>'; } else { // Is there an obliterated note? // There is not an obliterated note. Show playerplanet info without content. if ( DEBUG ) { console.log(TB+"There is not an obliterated note. Show gameplanet info with COLnext or 'Lost Contact'."); } ttContent_Planets += '<td class="narrow">'+Planettype[pp.TYPEp].Code+pp.HABp+PlanetNMsuffix[pp.NMp]+'</td>'; LostContact = ttLostContact(pp); ttContent_Planets += ''; if ( LostContact ) { // Did the player lose contact? ttContent_Planets += '<td class="errortext">Lost Contact</td>'; } else { if ( turnType === 'Production' && pp.COLnext > 0 ) { ttContent_Planets += '<td class="production">'+pp.COLnext+' COL</td>'; } else { ttContent_Planets += '<td></td>'; } } //ttContent_Planets += '<td class="narrow">=</td>'; ttContent_Planets += '<td class="narrow">v'+pp.VALp+'</td>'; } // Is there an obliterated note? } // Is this planet owned by another player? } else { // Is the player here? if ( DEBUG ) { console.info(PC+'The player is NOT here.',CI); } if ( DEBUG ) { console.info(PC+'Show production[r] planet info.',CD); } ttContent_Planets += '<td class="narrow">'+Planettype[pp.TYPEr].Code+pp.HABr+PlanetNMsuffix[pp.NMr]+'</td>'; // See if the player has 'Lost Contact' with the planet. LostContact = ttLostContact(pp); ttContent_Planets += ''; if ( LostContact ) { // Did the player lose contact? ttContent_Planets += '<td class="errortext">Lost Contact</td>'; //ttContent_Planets += '<td></td>'; //ttContent_Planets += '<td></td>'; } else { ttContent_Planets += '<td></td>'; //ttContent_Planets += '<td class="narrow">=</td>'; //ttContent_Planets += '<td class="narrow">v'+pp.VALp+'</td>'; } ttContent_Planets += '<td class="narrow">v'+pp.VALp+'</td>'; } // Is the player here? // Add DEBUG info. /** / if ( DEBUG ) { ttContent_Planets += '<td>'; if ( pp.LC === 0 ) { if ( pp.OW !== -1 ) { ttContent_Planets += 'OW='+pp.OW+' '+PlayerColorNames[pp.OW]+' #'+pn; } else { ttContent_Planets += 'NO #'+pn; } } else { ttContent_Planets += 'LC='+pp.OW+' '+PlayerColorNames[pp.OW]+' #'+pn; } ttContent_Planets += '</td>'; } /**/ ttContent_Planets += '</tr>'; // END tr. if ( DEBUG ) { console.groupEnd(); } } // Loop thru planets. ttContent_Planets += "\n\t"+'</tbody>'; ttContent_Planets += "\n"+'</table>'; } else { // This star has viewable planets. if ( DEBUG ) { console.info(PC+'This star does NOT have viewable planets.',CI); } if ( playerTurn > 0 ) { // Is this a normal turn? // This star has no planets. if ( DEBUG ) { console.info(PC+'This is a normal turn.',CI); } if ( DEBUG ) { console.info(PC+'Show no planets.',CD); } ttContent_Planets += '<table class="ttTable"><tbody><tr><td>No planets.</td></tr></tbody></table>'; } else { // Is this a normal turn? if ( DEBUG ) { console.info(PC+'This is a setup turn.',CI); } if ( playerAction === 'Select Techs' ) { // && playerScreen !== 'SelectTechs' ttContent_Planets += '<table class="ttTable"><tbody><tr><td><span style="color:' + PlayerColors[userId].Color + '; background-color;' + PlayerColors[userId].Background + ';">' + Mapstar[XY].Name + '</span> is your home system.</td></tr></tbody></table>'; } else if ( playerAction === 'Spend Initial RPs' ) { ttContent_Planets += '<table class="ttTable"><tbody><tr><td>You did not preview your home system.</td></tr></tbody></table>'; } } // Is this a normal turn? } // DOes this star have planets? } else { // Has this star been explored? // This star has NOT been explored. if ( DEBUG ) { console.info(PC+'This star has NOT been explored.',CI); } if ( playerTurn > 0 ) { // Is this a normal turn? // This star has no planets. if ( DEBUG ) { console.info(PC+'This is a normal turn.',CI); } if ( DEBUG ) { console.info(PC+'Show unexplored.',CD); } ttContent_Planets += '<table class="ttTable"><tbody><tr><td>Unexplored.</td></tr></tbody></table>'; } else { // Is this a normal turn? if ( DEBUG ) { console.info(PC+'This is a setup turn.',CI); } if ( DEBUG ) { console.info(PC+'Show nothing.',CD); } //ttContent_Planets += '<table class="ttTable"><tbody><tr><td>Unexplored.</td></tr></tbody></table>'; } // Is this a normal turn? } // Has this star been explored? } else { // Is this a star? if ( DEBUG ) { console.info('Mapstar['+XY+'] is undefined.'); } } // Is this a star? if ( DEBUG ) { console.info(PC+'ttContent_Planets='+"\n"+ttContent_Planets,CI); //DEBUG_textarea_Load(ttContent_Planets); } if ( DEBUG ) { console.groupEnd(); } if ( DEBUG ) { console.log(PC+'END ttDisplay_Planets.',CG); } return ttContent_Planets; } // END ttDisplay_Planets. // ttDisplay_Planets_Contents(pn, uId) // Return planet contents. This function is only called by ttDisplay_Planets(). // pn = planet number. // uId = If set show contents in uId's color else set uId to userId and use userId's color. // If enemy warships or OBs are present return nothing; else if only GBs are present show only GBs; else show all POPCOL and units. function ttDisplay_Planets_Contents(pn, uId) { let DEBUG = DEBUG_OFF; if ( typeof uId === 'undefined' ) { uId = userId; } if ( DEBUG ) { console.group(PC+'ttDisplay_Planets_Contents[pn='+pn+', uId='+uId+']',CG); } let planetContent = ''; let unitQty = 0; let tuId = 0; if ( DEBUG && ( typeof PP[pn] !== 'undefined' ) ) { console.log(PC+'PP['+pn+']='+JSON.stringify(PP[pn]),CI); } if ( DEBUG ) { console.log(PC+"( typeof PP["+pn+"] !== 'undefined' )="+( typeof PP[pn] !== 'undefined' ),CL); } if ( DEBUG ) { console.log(PC+'IsPlayerHere(PP['+pn+'].XY)='+IsPlayerHere(PP[pn].XY,'ttDisplay_Planets_Contents'),CL); } //function dfdf() { if ( PP[pn].Note.indexOf('Lost Contact|'+userId) !== -1 || PP[pn].Note.indexOf('TakeOver:userId='+userId) !== -1 || PP[pn].Note.indexOf('Production:userId='+userId) !== -1 ) { // Is the player the TKO player? PlanetIsCoveredBySpaceCombatUnits = false; } else { PlanetIsCoveredBySpaceCombatUnits = ttEnemyHasSpaceCombatUnits(PP[pn].OW); } //} if ( PP[pn].Note.indexOf('Lost Contact|'+userId) !== -1 || PP[pn].Note.indexOf('TakeOver:userId='+userId) !== -1 || PP[pn].Note.indexOf('Production:userId='+userId) !== -1 ) { // Is the player the TKO player? PlanetIsCoveredBySpaceCombatUnits = false; } else { PlanetIsCoveredBySpaceCombatUnits = ttEnemyHasSpaceCombatUnits(PP[pn].OW); } let enemyHasGB = false; let planetContents = []; if ( uId !== userId ) { // Should we check for GBs? // Yes, check for GBs. for ( tuId in PPU[pn] ) {if(PPU[pn].hasOwnProperty(tuId)) { // Loop thru Techunit. if ( DEBUG ) { console.log(PC+Techunit[tuId].Name+ ' PPU['+pn+']['+tuId+']='+PPU[pn][tuId]+' Techunit['+tuId+'].Att='+Techunit[tuId].Att,CL); } if ( ( Techunit[tuId].Att > 0 ) && PPU[pn][tuId] ) { // Are there GBs? enemyHasGB = true; // Set true again. break; // Exit loop since GB found. } // Are there GBs? }} // Loop thru Techunit. } // Should we check for GBs? let enemyHasPlanetCover = PlanetIsCoveredBySpaceCombatUnits || enemyHasGB; if ( typeof PP[pn] !== 'undefined' && IsPlayerHere(PP[pn].XY,'ttDisplay_Planets_Contents') ) { // Does player have PP data and is player here? { // BEGIN Add POPCOL. if ( DEBUG ) { console.groupCollapsed(PC+'BEGIN Add POPCOL',CG); } if ( DEBUG ) { console.log('enemyHasPlanetCover='+enemyHasPlanetCover+' enemyHasGB='+enemyHasGB+' PlanetIsCoveredBySpaceCombatUnits='+PlanetIsCoveredBySpaceCombatUnits); } if ( !enemyHasPlanetCover ) { // Are their no GB or should GBs not be checked for? // Yes, GBs do not matter, show contents. let POPCOL = PP[pn].POP+PP[pn].COL; let POPCOLnext = PP[pn].POPnext+PP[pn].COLnext; if ( DEBUG ) { console.log(PC+'POPCOL='+POPCOL+' POPCOLnext='+POPCOLnext,CL); } let POPCOLclass = ''; let POPCOLtext; if ( POPCOLnext !== 0 ) { // Is there POPCOL next turn? if ( playerAction !== 'Production' || PP[pn].LC ) { // Is this a production turn or planet is TKO or PRD? // Yes, this is not a production turn or planet is TKO or PRD. if ( DEBUG ) { console.log(PC+'Not a production turn or planet is taken over.',CI); } // Add POPCOL. let POPCOLspan = ''; if ( POPCOLnext === PP[pn].HABp ) { POPCOLclass = '<span class="info">'; POPCOLspan = '</span>'; } POPCOLtext = POPCOLclass+POPCOLnext+' '; if ( PP[pn].POPnext ) { POPCOLtext += 'POP'; if ( PP[pn].COLnext ) { POPCOLtext +='+'; } } else if ( PP[pn].COLnext ) { POPCOLtext += 'COL'; } POPCOLtext += POPCOLspan; planetContents.push(POPCOLtext); } else { // Is this a production turn or planet is TKO or PRD? // No, This is a production turn and the planet is not TKO or PRD. if ( DEBUG ) { console.log(PC+'A production turn and planet is not taken over.',CI); } // Production. Show POPnext + COLnext as POPCOL. if ( POPCOLnext === PP[pn].HABr && PP[pn].HABp === PP[pn].HABr ) { POPCOLclass = 'info'; } else { if ( POPCOL === POPCOLnext ) { POPCOLclass = ''; } else { POPCOLclass = 'production'; } } POPCOLtext = ' <span class="'+POPCOLclass+'">'+POPCOLnext+' '; if ( PP[pn].POPnext ) { POPCOLtext += 'POP'; if ( PP[pn].COLnext ) { POPCOLtext +='+'; } } else if ( PP[pn].COLnext ) { POPCOLtext += 'COL'; } POPCOLtext += '</span>'; planetContents.push(POPCOLtext); } // Is this a production turn or planet is TKO or PRD? if ( DEBUG ) { console.log(PC+'POPCOLtext='+POPCOLtext,CL); } } else { // Is there POPCOL next turn? if ( DEBUG ) { console.log(PC+'There is no POP or COL next turn.',CF); } } // Is there POPCOL next turn? } else { // Are their no GB or should GBs not be checked for? if ( DEBUG ) { console.log('Space combat units or GBs hide planet contents.'); } } // Are their no GB or should GBs not be checked for? if ( DEBUG ) { console.groupEnd(); } if ( DEBUG ) { console.log(PC+'END Add POPCOL',CG); } // END Add POPCOL. } { // BEGIN Add units. if ( DEBUG ) { console.groupCollapsed(PC+'BEGIN Add units',CG); } if ( DEBUG ) { console.log(PC+'PPU['+pn+']='+JSON.stringify(PPU[pn])+' PPR['+pn+']='+JSON.stringify(PPR[pn]),CI); } if ( ( typeof PPU[pn] !== 'undefined' ) || ( typeof PPR[pn] !== 'undefined' ) ) { // Does this planet have units? for ( let tuIndex=0; tuIndex<TechunitIds.length; tuIndex++ ) { tuId = TechunitIds[tuIndex]; let UnitClassBegin = ''; let UnitClassEnd = ''; if ( DEBUG ) { console.log(PC+'!enemyHasPlanetCover='+!enemyHasPlanetCover+' Techunit['+tuId+'].Att='+Techunit[tuId].Att,CL); } if ( ( !enemyHasPlanetCover || Techunit[tuId].Att > 0 ) ) { // Is the enemy planet not protected or is this a GB unit? // Yes, planet contents can be displayed. if ( DEBUG ) { console.log(PC+'This unit ('+Techunit[tuId].Name+') can be displayed.',CT); } let unitText = ''; if ( Techunit[tuId].Special.text.search('RP=') !== -1 ) { // Is this an IU or RU unit? if ( PPU[pn][tuId] === 200 ) { UnitClassBegin = '<span class="info">'; UnitClassEnd = '</span>'; } } // Is this an IU or RU unit? if ( DEBUG ) { console.log(PC+'playerAction='+playerAction+' (typeof PPR['+pn+']['+tuId+']===\'undefined\')='+( typeof PPR[pn][tuId] === 'undefined' ),CL); } if ( playerAction !== 'Production' || ( typeof PPR[pn][tuId] === 'undefined' ) ) { // Is this not a production turn or PPR for this unit is undefined? // Yes, this not a production turn or PPR for this unit is undefined. if ( DEBUG ) { console.log(PC+'This not a production turn or PPR for this unit is undefined.',CL); } if ( PPU[pn][tuId] ) { unitText = UnitClassBegin+PPU[pn][tuId]+' '+Techunit[tuId].Name; if ( PPU[pn][tuId] > 1 ) { unitText += 's'; } } unitText += UnitClassEnd; } else { // Is this not a production turn or PPR for this unit is undefined? // No, this is a production turn and PPR for this unit is defined. if ( DEBUG ) { console.log(PC+'This is a production turn and PPR for this unit is defined.',CL); } if ( PPU[pn][tuId] || PPR[pn][tuId] ) { //console.log(PC+'PPU='+PPU[pn][tuId]+' PPR '+JSON.stringify(PPR[pn][tuId]),CI); unitQty = 0; if ( PPU[pn][tuId] > 0 ) { unitQty += PPU[pn][tuId]; } if ( PPR[pn][tuId] > 0 ) { unitQty += PPR[pn][tuId]; } unitText = '<span class="production">'+unitQty+' '+Techunit[tuId].Name; if ( unitQty > 1 ) { unitText += 's'; } unitText += '</span>'; } } // Is this not a production turn or PPR for this unit is undefined? if ( unitText) { planetContents.push(unitText); } } else { // Is the enemy planet not protected or is this a GB unit? if ( DEBUG ) { console.log(PC+'The enemy planet is protected and this unit ('+Techunit[tuId].Name+') is not a GB unit.',CF); } } // Is the enemy planet not protected or is this a GB unit? } } // Does this planet have units? if ( DEBUG ) { console.groupEnd(); } if ( DEBUG ) { console.log(PC+'END Add units',CG); } // END Add units. } // Display planetContents. if ( planetContents.length ) { let prefix = ''; let planetContentsEnd = planetContents.length - 1; if ( planetContentsEnd === 0 ) { planetContentsEnd = -1; } for ( let c=0; c<planetContents.length; c++ ) { planetContent += prefix; if ( c === planetContentsEnd ) { planetContent += 'and '; } planetContent += planetContents[c]; if ( planetContentsEnd > 1 ) { prefix = ', '; } else { prefix = ' '; } } } if ( DEBUG ) { console.log('userId='+userId+' uId='+uId); } if ( userId !== uId && uId > 0 ) { planetContent = '<span style="color:'+PlayerColors[uId].Color+'; background-color:'+PlayerColors[uId].Background+';">'+planetContent+'</span>'; } } else { // Does player have PP data and is player here? if ( DEBUG ) { console.log('Player does not have data for planet #'+pn+' or is not here.'); } } // Does player have PP data and is player here? //if ( planetContent === '' ) { planetContent = ' '; } if ( DEBUG ) { console.log('planetContent='+planetContent); } if ( DEBUG ) { console.groupEnd(); } return planetContent; } // END ttDisplay_Planets_Contents. // ttDisplay_Production() // Display in space units produced at XY. function ttDisplay_Production() { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('ttDisplay_Production[] XY='+XY+''); } //if ( DEBUG ) console.log('playerScreen='+playerScreen); let ttContent_Production = ''; let totalCost = 0; let InSpaceProductionContent = ''; let InSpaceProductionCTs = 0; let PlanetProductionContent = ''; let prefix; if ( playerAction === 'Production' ) { // Is this a production screen? // In space production. let InSpaceProduction = []; let t; let tuId; let unitText; if ( typeof PSR[XY] !== 'undefined' ) { // Was there ship or OB production here? for ( t=0; t<TechunitIds.length; t++ ) { // Loop thru tech units. tuId = TechunitIds[t]; if ( typeof PSR[XY][tuId] !== 'undefined' && PSR[XY][tuId] > 0 ) { // Was this unit built? unitText = PSR[XY][tuId] + ' ' + Techunit[tuId].Name + Techunit[tuId].NameSuffix; if ( PSR[XY][tuId] > 1 ) { unitText += 's'; } totalCost += Techunit[tuId].Cost * PSR[XY][tuId]; InSpaceProduction.push(unitText); } // Was this unit built? } // Loop thru tech units. // id_CTsInSpace_2416 thisQty = getValue('id_CTsInSpace',XY); if ( DEBUG ) { console.log('thisQty='+thisQty); } if ( thisQty ) { //InSpaceProductionCTs += thisQty; InSpaceProductionCTs = thisQty+' '+Techunit[POPtransport_tuId].Name; if ( thisQty > 1 ) { InSpaceProductionCTs += 's'; } InSpaceProductionCTs += ' in space here'; } } // Was there ship or OB production here? if ( InSpaceProduction.length ) { prefix = ''; let InSpaceProductionEnd = InSpaceProduction.length - 1; if ( InSpaceProductionEnd === 0 ) { InSpaceProductionEnd = -1; } for ( let c=0; c<InSpaceProduction.length; c++ ) { InSpaceProductionContent += prefix; if ( c === InSpaceProductionEnd ) { InSpaceProductionContent += 'and '; } InSpaceProductionContent += InSpaceProduction[c]; if ( InSpaceProductionEnd > 1 ) { prefix = ', '; } else { prefix = ' '; } } } // Planet production. let PlanetProduction = []; let pn; if ( typeof PPXY[XY] !== 'undefined' ) { // Are there planets here? prefix = ''; for ( let p=0; p<PPXY[XY].length; p++ ) { // Loop thru planets at star. PlanetProduction[p] = ''; pn = PPXY[XY][p]; for ( t=0; t<TechunitIds.length; t++ ) { // Loop thru tech units. tuId = TechunitIds[t]; if ( typeof PPR[pn] !== 'undefined' && typeof PPR[pn][tuId] !== 'undefined' && PPR[pn][tuId] > 0 ) { // Was this unit built? unitText = PPR[pn][tuId] + ' ' + Techunit[tuId].Name; if ( Techunit[tuId].NameSuffix ) { if ( Techunit[tuId].Name !== 'AM' ) { unitText += Techunit[tuId].NameSuffix; } } else { if ( PPR[pn][tuId] > 1 ) { unitText += 's'; } } if ( Techunit[tuId].Cost ) { totalCost += Techunit[tuId].Cost * PPR[pn][tuId]; } else if (Techunit[tuId].CostSpecial.code && Techunit[tuId].CostSpecial.code === 'RP' ) { // Does this unit have a CostSpecial.code? // Yes, use it. // Currently only AM has a special cost and it is planetHAB_Begin. totalCost += PP[pn].HAB; } PlanetProduction[p] += prefix+unitText; prefix = ', '; } else { //PlanetProduction[p] = ''; } // Was this unit built? } // Loop thru tech units. } // Loop thru planets at star. prefix = ''; for ( p=0; p<PPXY[XY].length; p++ ) { // Loop thru planets at star. let pd = p+1; pn = Mapstar[XY].PNs[p]; if ( PlanetProduction[p] !== '' ) { //if ( PP[pn].OW == userId ) { // Is this planet owned by the user? if ( PP[pn].OW > 0 ) { // Is this planet owned by the user? PlanetProductionContent += prefix+'<span style="color:'+PlayerColors[PP[pn].OW].Color+'; background-color:'+PlayerColors[PP[pn].OW].Background+';">'+pd+')</span> '; } else { PlanetProductionContent += prefix+pd+') '; } ProductionChangeClass = ''; if ( ttPlanetIsOriginal(pn) ) { if ( ttPlanetIsPlayer(pn) ) { PlanetProductionContent += Planettype[PP[pn].TYPEp].Code + PP[pn].HABp + PlanetNMsuffix[PP[pn].NMp]; } else { // Show player changed and set to show production. PlanetProductionContent += '<span class="planetChange">'; PlanetProductionContent += Planettype[PP[pn].TYPEp].Code + PP[pn].HABp + PlanetNMsuffix[PP[pn].NMp]; PlanetProductionContent += '</span> '; ProductionChangeClass = 'production'; } } else { // Show original changed. PlanetProductionContent += '<span class="planetChange">'; PlanetProductionContent += Planettype[PP[pn].TYPEo].Code + PP[pn].HABo + PlanetNMsuffix[PP[pn].NMo]; PlanetProductionContent += '</span> '; if ( ttPlanetIsPlayer(pn) ) { // Show player. PlanetProductionContent += Planettype[PP[pn].TYPEp].Code + PP[pn].HABp + PlanetNMsuffix[PP[pn].NMp]; } else { // Show player changed and set to show production. PlanetProductionContent += '<span class="planetChange">'; PlanetProductionContent += Planettype[PP[pn].TYPEp].Code + PP[pn].HABp + PlanetNMsuffix[PP[pn].NMp]; PlanetProductionContent += '</span> '; ProductionChangeClass = 'production'; } } if ( ProductionChangeClass === 'production' ) { // Show production. ttContent_Planets += '<span class="production">'; ttContent_Planets += Planettype[PP[pn].TYPEr].Code + PP[pn].HABr + PlanetNMsuffix[PP[pn].NMr]; ttContent_Planets += '</span> '; VAL = PP[pn].VALr; } PlanetProductionContent += ' <span class="production">'+PlanetProduction[p]+'</span>'; prefix = '<br>'; } } } // Are there planets here? } // Is this a production screen? if ( InSpaceProductionContent || InSpaceProductionCTs || PlanetProductionContent ) { ttContent_Production += '<table class="ttTable">'; ttContent_Production += "\n\t"+'<thead><tr><th class="production">Production <span class="normal">('+totalCost+' RP'; if ( totalCost > 1 ) { ttContent_Production += 's'; } ttContent_Production += ')</span></th></tr></thead>'; ttContent_Production += "\n\t"+'<tbody>'; if ( InSpaceProductionContent ) { ttContent_Production += "\n\t"+'<tr><td class="production">'+InSpaceProductionContent+'</td></tr>'; } if ( InSpaceProductionCTs ) { ttContent_Production += "\n\t"+'<tr><td class="production">'+InSpaceProductionCTs+'</td></tr>'; } if ( PlanetProductionContent ) { ttContent_Production += "\n\t"+'<tr><td class="xproduction">'+PlanetProductionContent+'</td></tr>'; } ttContent_Production += "\n\t"+'</tbody>'; ttContent_Production += "\n"+'</table>'; } if ( DEBUG ) { console.log('ttContent_Production='+ttContent_Production); } return ttContent_Production; } // END ttDisplay_Production. // ttDisplay_onClick() // Display the onClick task. function ttDisplay_onClick() { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('ttDisplay_onClick[] XY='+XY+' playerScreen='+playerScreen); } ttContent_onClick = ''; switch ( playerScreen ) { case 'Movement': CanvasClickFunction[XY] = false; if ( typeof PlayerfleetByXY !== 'undefined' ) { // Are there fleets? if ( typeof PlayerfleetByXY[XY] !== 'undefined' ) { // Are there fleets here? if ( DEBUG ) { console.log('PlayerfleetByXY['+XY+']='+PlayerfleetByXY[XY]); } fleetCanMove = false; if ( typeof Mapstar[XY] !== 'undefined' || Techlimit.movement.change !== 'star' ) { // Is this is a star or does the player have USC? fleetCanMove = true; if ( DEBUG ) { console.log('This is a star or player has USC. fleetCanMove='+fleetCanMove); } } else { // Is this is a star or does the player have USC? // Check if fleet is running or stuck in space. if ( DEBUG ) { console.log('PlayerfleetByXY['+XY+']='+PlayerfleetByXY[XY]); } for ( let FleetIndex=0; FleetIndex<PlayerfleetByXY[XY].length; FleetIndex++ ) { // Loop thru PlayerfleetByXY[XY]s. let UN = PlayerfleetByXY[XY][FleetIndex]; let fleetName = PF[UN].Name; if ( PF[UN].userId === userId && ( PF[UN].Action.substring(0,3) === 'Run' || ( PF[UN].dTurns <= 0 && Techlimit.movement.change === 'star' ) ) ) { fleetCanMove = true; if ( DEBUG ) { console.log('Fleet is running. fleetCanMove='+fleetCanMove); } } } // Loop thru PlayerfleetByXY[XY]s. } // Is this is a star or does the player have USC? if ( fleetCanMove ) { // Can this fleet move? if ( typeof Mapstar[XY] !== 'undefined' ) { ttContent_onClick = '<span class="action">Click on star to perform movement.</span>'+"\n"; if ( DEBUG ) { console.log('ttContent_onClick='+ttContent_onClick); } } else { ttContent_onClick = '<span class="action">Click on hex to perform movement.</span>'+"\n"; if ( DEBUG ) { console.log('ttContent_onClick='+ttContent_onClick); } } CanvasClickFunction[XY] = function() { moveDisplay('MapMenu',XY, 'ttDisplay_onClick 3448'); }; } else { // Can this fleet move? if ( DEBUG ) { console.log('Fleet cannot move. fleetCanMove='+fleetCanMove); } } // Can this fleet move? } else { // Are there fleets here? if ( DEBUG ) { console.info('There are no fleets at '+XY+'.'); } } // Are there fleets here? } else { // Are there fleets? if ( DEBUG ) { console.info('There are no fleets.'); } } // Are there fleets? // Assign onClick for ships. if ( typeof playershipXYs !== 'undefined' && playershipXYs.indexOf(XY) !== -1 ) { // Are there ships here? ttContent_onClick = '<span class="action">Click on star to perform movement.</span>'+"\n"; if ( DEBUG ) { console.log('ttContent_onClick='+ttContent_onClick); } CanvasClickFunction[XY] = function() { moveDisplay('MapMenu',XY, 'ttDisplay_onClick 33462'); }; } // Are there ships here? if ( !CanvasClickFunction[XY] && typeof Mapstar[XY] !== 'undefined' ) { ttContent_onClick = '<span class="action">Click to make note.</span>'+"\n"; CanvasClickFunction[XY] = function() { starNoteDisplay(XY); }; } break; case 'Production': if ( DEBUG ) { console.log('( typeof productionXYs != \'undefined\' )='+( typeof productionXYs !== 'undefined' )); } if ( typeof productionXYs !== 'undefined' ) { // Are productionXYs defined? if ( DEBUG ) { console.log('productionXYs='+productionXYs); } if ( typeof Mapstar[XY] !== 'undefined' && productionXYs.indexOf(XY) !== -1 ) { // Is this XY a star in productionXYs? // Add onclick for production at XY. if ( document.getElementById('btnSpend_'+XY) ) { ttContent_onClick = '<span class="action">Click on star to spend.</span>'+"\n"; CanvasClickFunction[XY] = function() { document.getElementById('btnSpend_'+XY).click(); }; } else { if ( typeof Mapstar[XY] !== 'undefined' && playerTurn > 0 ) { ttContent_onClick = '<span class="action">Click to make note.</span>'+"\n"; } CanvasClickFunction[XY] = function() { starNoteDisplay(XY); }; } } else { // Is this XY a star in productionXYs? // Add onclick for note. if ( typeof Mapstar[XY] !== 'undefined' && playerTurn > 0 ) { ttContent_onClick = '<span class="action">Click to make note.</span>'+"\n"; } CanvasClickFunction[XY] = function() { starNoteDisplay(XY); }; } // Is this XY a star in productionXYs? } else { // Are productionXYs defined? if ( DEBUG ) { console.log('( typeof ProductionSelectNewHome != \'undefined\' )='+( typeof ProductionSelectNewHome !== 'undefined' )); } if ( ( typeof ProductionSelectNewHome !== 'undefined' ) && ProductionSelectNewHome && starXY.indexOf(XY) !== -1 ) { if ( DEBUG ) { console.log(XY+' is a possible new home system.'); } // XY is a possible new home system. ttContent_onClick = '<span class="action">Click to select '+Mapstar[XY].Name+' to be your new home system.</span>'+"\n"; CanvasClickFunction[XY] = function() { HomeSystemSelect(this,XY); }; } else { // Add onclick for note. if ( typeof Mapstar[XY] !== 'undefined' && playerTurn > 0 ) { ttContent_onClick = '<span class="action">Click to make note.</span>'+"\n"; } CanvasClickFunction[XY] = function() { starNoteDisplay(XY); }; } } // Are productionXYs defined? break; case 'ReselectHome': case 'SelectHome': if ( typeof Mapstar[XY] !== 'undefined' ) { let sXY = Mapstar[XY].XY; ttContent_onClick = '<span class="action">Select '+Mapstar[XY].Name+' as your home system.</span>'+"\n"; CanvasClickFunction[XY] = function() { SelectHome(XY); }; } break; case 'SelectTechs': if ( typeof Mapstar[XY] !== 'undefined' && !GameInfo.previewHome ) { if ( XY !== homeSystem ) { ttContent_onClick = '<span class="info">'+Mapstar[XY].Name+' is not your home system.</span>'+"\n"; } else { ttContent_onClick = '<span class="attention">Click to preview your home system.<br>This costs 4 points and may not be cancelled.</span>'+"\n"; CanvasClickFunction[XY] = function() { formSubmit('mapWrapper',{'subtask':'Preview Home'}); }; } } break; default: if ( DEBUG ) { console.log(PC+TB+'default (typeof Mapstar['+XY+'] !== \'undefined\')='+(typeof Mapstar[XY] !== 'undefined')+' playerAction='+playerAction,CI); } if ( typeof Mapstar[XY] !== 'undefined' && playerAction !== 'Configure Game' && playerAction !== 'Select Techs' && playerAction !== 'Spend Initial RPs' ) { ttContent_onClick = '<span class="action">Click to make note.</span>'+"\n"; CanvasClickFunction[XY] = function() { starNoteDisplay(XY); }; } break; } if ( DEBUG ) { console.log('ttContent_onClick='+ttContent_onClick); } return ttContent_onClick; } // END ttDisplay_onClick. // ttDisplay_TKO(TKO_XY) // Display warning if TKO needs cover here. function ttDisplay_TKO(TKO_XY) { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.log('ttDisplay_TKO[TKO_XY='+TKO_XY+']'); } ttContent_TKO = ''; if ( ( typeof TKOsThatWereAbandoned !== 'undefined' ) && TKOsThatWereAbandoned.indexOf(TKO_XY) !== -1 ) { // Is there a TKO abandoned here? ttContent_TKO = '<div><span class="warntext">Take over at </span>'+Startype[Mapstar[TKO_XY].startypeId].ColorSpan+' '+Mapstar[TKO_XY].Name+'<span class="small"> ['+TKO_XY+']</span><span class="warntext"> will be abandoned.</span></div>'; } // Is there a TKO abandoned here? return ttContent_TKO; } // END ttDisplay_TKO. // ttEnemyHasSpaceCombatUnits(eId) // Returns true if the enemy has space combat units (warships or orbital bases). function ttEnemyHasSpaceCombatUnits(eId) { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.groupCollapsed(PC+'ttEnemyHasSpaceCombatUnits[eId='+eId+', XY='+XY+']',CG); } let EnemyHasSpaceCombatUnits = false; if ( DEBUG ) { console.log(PC+'PlayerStatus['+eId+'].Turn='+PlayerStatus[eId].Turn+' playerTurn='+playerTurn,CL); } if ( eId !== userId ) { // Check enemy fleets for warships. let tuId; FleetLoop: for ( let UN in PF ) {if(PF.hasOwnProperty(UN)) { // Loop thru fleets. if ( DEBUG ) { console.log(PC+'PF['+UN+'].userId='+PF[UN].userId+' PF['+UN+'].XY='+PF[UN].XY,CL); } if ( eId === PF[UN].userId && PF[UN].XY === XY ) { // Does this fleet belong to the enemy we are looking for and is it at the correct XY? if ( DEBUG ) { console.log(PC+'PF['+UN+']='+JSON.stringify(PF[UN]),CL); } if ( PlayerStatus[eId].Turn <= playerTurn || PF[UN].dTurns === -1 ) { // Is the player NOT in the future or was the fleet already here? for ( tuId in PFU[UN] ) {if(PFU[UN].hasOwnProperty(tuId)) { // Loop thru fleet units. if ( DEBUG ) { console.log('UN='+UN+' tuId='+tuId+'='+PFU[UN][tuId]);} if ( PFU[UN][tuId] > 0 && Techunit[tuId].Type ==='warship' ) { EnemyHasSpaceCombatUnits = true; break FleetLoop; // Warship found, loop can stop. } } // Is the player NOT in the future or was the fleet already here? }} // Loop thru fleet units. } // Does this fleet belong to the enemy we are looking for and is it at the correct XY? }} // Loop thru fleets. let UXY; if ( !EnemyHasSpaceCombatUnits ) { // Have enemy warships not been found? // Check enemy ships for warships. UXY = eId+'_'+XY; if ( typeof PSU[UXY] !== 'undefined' ) { // Are there enemy ships? for ( tuId in PSU[UXY] ) {if(PSU[UXY].hasOwnProperty(tuId)) { // Loop thru enemy ships. if ( DEBUG ) { console.log('UXY='+UXY+' tuId='+tuId+'='+PSU[UXY][tuId]); } if ( PSU[UXY][tuId] > 0 && Techunit[tuId].Type ==='warship' ) { EnemyHasSpaceCombatUnits = true; break; // Warship found, loop can stop. } }} // Loop thru enemy ships. } // Are there enemy ships? } // Have enemy warships not been found? if ( !EnemyHasSpaceCombatUnits ) { // Have enemy warships not been found? // Check for enemy orbital bases. UXY = eId+'_'+XY; if ( typeof POU[UXY] !== 'undefined' ) { // Are there enemy orbital bases? for ( tuId in POU[UXY] ) {if(POU[UXY].hasOwnProperty(tuId)) { // Loop thru enemy orbital bases. if ( DEBUG ) { console.log('UXY='+UXY+' tuId='+tuId+'='+POU[UXY][tuId]); } if ( POU[UXY][tuId] > 0 && Techunit[tuId].Type ==='orbital' ) { EnemyHasSpaceCombatUnits = true; break; // Orbital base found, loop can stop. } }} // Loop thru enemy orbital bases. } // Are there enemy orbital bases? } // Have enemy warships not been found? } else { if ( DEBUG ) { console.log('This is the player.'); } } if ( DEBUG ) { console.log('EnemyHasSpaceCombatUnits='+EnemyHasSpaceCombatUnits); } if ( DEBUG ) { console.groupEnd(); } return EnemyHasSpaceCombatUnits; } // END ttEnemyHasSpaceCombatUnits. // ttLostContact(pp) // Return true if the player has 'Lost Contact' with this planet in the past, else false. // Will also return false if there is a 'Contact Restored', 'Explore' or 'Take Over' event before any 'Lost Contact' is found. function ttLostContact(pp) { let DEBUG = DEBUG_OFF; if ( DEBUG ) { console.group(PC+'ttLostContact[pp='+pp+']',CG); } LostContact = false; if ( ( typeof Events[userId] !== 'undefined' ) && ( typeof Events[userId][pp.XY] !== 'undefined' ) ) { // Does the player have events here? if ( DEBUG ) { console.info(PC+'The player has events here.',CI); } for ( let ei=0; ei<Events[userId][pp.XY].length; ei++ ) { // Loop thru events. if ( DEBUG ) { console.log(PC+TB+'Events[userId]['+pp.XY+']['+ei+'].action='+Events[userId][pp.XY][ei].action,CL); } if ( Events[userId][pp.XY][ei].action === 'Contact Restored' || Events[userId][pp.XY][ei].action === 'Explore' || Events[userId][pp.XY][ei].action === 'Take Over' ) { break; } if ( Events[userId][pp.XY][ei].action === 'Lost Contact' ) { LostContact = true; break; } } // Loop thru events. } else { if ( DEBUG ) { console.info(PC+'The player does NOT have events here.',CI); } } if ( DEBUG ) { console.info(PC+'LostContact='+LostContact,CI); } if ( LostContact !== 0 && pp.OW === userId && pp.LC !== 0 ) { if ( DEBUG ) { console.info(PC+'The player skipped \'Lost Contact\'.',CI); } LostContact = true; } if ( DEBUG ) { console.groupEnd(); } return LostContact; } // END ttLostContact. // ttPd(pn) // Return planet description for console DEBUGging. function ttPd(pn) { if ( typeof PP[pn] !== 'undefined' ) { //console.log('Mapstar['+XY+'].PNs.indexOf('+pn+')'+Mapstar[XY].PNs.indexOf(pn)); return (Mapstar[XY].PNs.indexOf(pn)+1)+'☽ '+Planettype[PP[pn].TYPEp].Code + PP[pn].HABp + PlanetNMsuffix[PP[pn].NMp]; } else { return ''; } } // END ttPd. // ttPlanetIsOriginal() // Returns true if the planet has original TYPE HAB NM, else false. // pn = planet number. function ttPlanetIsOriginal(pn) { //console.log('ttPlanetIsOriginal PP[pn].TYPEo+PP[pn].HABo+PP[pn].NMo='+PP[pn].TYPEo+PP[pn].HABo+PP[pn].NMo+' PP[pn].TYPEp+PP[pn].HABp+PP[pn].NMp='+PP[pn].TYPEp+PP[pn].HABp+PP[pn].NMp+' is '+(PP[pn].TYPEo+PP[pn].HABo+PP[pn].NMo === PP[pn].TYPEp+PP[pn].HABp+PP[pn].NMp)); if ( PP[pn].TYPEo+PP[pn].HABo+PP[pn].NMo === PP[pn].TYPEp+PP[pn].HABp+PP[pn].NMp ) { return true; } else { return false; } } // END ttPlanetIsOriginal. // ttPlanetIsPlayer() // Returns true if the planet TYPE HAB NM has not been changee by production, else false. // pn = planet number. function ttPlanetIsPlayer(pn) { //console.log('PP['+pn+'].TYPEp='+PP[pn].TYPEp+' PP['+pn+'].HABp='+PP[pn].HABp+' PP['+pn+'].NMp='+PP[pn].NMp); //console.log('PP['+pn+'].TYPEr='+PP[pn].TYPEr+' PP['+pn+'].HABr='+PP[pn].HABr+' PP['+pn+'].NMr='+PP[pn].NMr); if ( typeof PP[pn].NMr === 'undefined' ) { PP[pn].NMr = PP[pn].NMp; } if ( PP[pn].TYPEp+PP[pn].HABp+PP[pn].NMp === PP[pn].TYPEr+PP[pn].HABr+PP[pn].NMr ) { return true; } else { return false; } } // END ttPlanetIsPlayer. // ttTR(turn) // Returns TR. function ttTR(turn) { let turnNumber = parseInt( turn / ( GameInfo.productionYearInterval * 2 + 1 ) + 0.0001 ) + 1; let TR = turnNumber; let Tround = turn % ( GameInfo.productionYearInterval * 2 + 1 ); if ( Tround !== 0 ) { TR += ( parseInt( ( Tround - 1 ) / 2 ) + 1 ) / 10; } else { TR += '.0'; } //console.log('turn='+turn+' turnNumber='+turnNumber+' TR='+TR+' Tround='+Tround); return TR; } // END ttTR.