Page MenuHomePhabricator

No OneTemporary

diff --git a/index.html b/index.html
index 8cfca13..1bb8a88 100644
--- a/index.html
+++ b/index.html
@@ -1,131 +1,136 @@
<!DOCTYPE html>
<html>
<head>
<title id="progtitle">3DCycles</title>
<link rel="icon" type="image/x-icon" href="favicon.ico"/>
<link rel="stylesheet" type="text/css" href="styles/main.css"/>
<link rel="stylesheet" type="text/css" href="styles/arma.css"/>
<script type="text/javascript" src="test.js"></script>
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport'/>
<script type="text/javascript" src="scripts/lib/Three.js"></script><!-- webgl framework -->
<script type="text/javascript" src="scripts/lib/legacy/Projector.js"></script><!-- needed for softwarerenderer -->
<script type="text/javascript" src="scripts/lib/legacy/SoftwareRenderer.js"></script><!-- canvas renderer for older browsers -->
<script type="text/javascript" src="scripts/lib/Detector.js"></script><!--//detects webgl renderer -->
<script type="text/javascript" src="scripts/lib/OBJExporter.js"></script>
<script type="text/javascript" src="scripts/lib/OBJLoader.js"></script><!-- webgl framework addon for obj loading -->
<script type="text/javascript" src="scripts/lib/rAF.js"></script><!-- requestAnimationFrame shim/polyfill -->
<script type="text/javascript" src="scripts/lib/OrbitControls.js"></script><!-- camera orbit -->
<script type="text/javascript" src="scripts/lib/SceneUtils.js"></script>
<script type="text/javascript" src="scripts/lib/xmllint.js"></script><!-- XML verification -->
<script type="text/javascript" src="scripts/functions-head.js"></script><!-- predefined functions that can be in head -->
<script type="text/javascript" src="scripts/lib/buffer-loader.js"></script><!-- buffer loader for sound -->
<script type="text/javascript" src="scripts/sound.js"></script><!-- loading sound files -->
</head>
<body>
+ <div id="inputbuttons">
+ <button class="cancel" onclick='keyboardKeyDown({keyCode:27});'>Cancel input</button>
+ <button class="bindtoesc" onclick="keyboardKeyDown({keyCode:27,forceHACK:true});">Bind to Escape key</button>
+ </div>
+
<div id="input">
<span>Say:</span>&nbsp;<input type="text" class="fakemenu-active" onblur="if(engine.inputState.substr(0,5)=='input')keyboardKeyDown({keyCode:27})"/>
</div>
<div id="menu-tooltip"></div>
<div id="menu" class="noselect mainbg_img"><h1>3DCycles is loading...</div>
<pre id="console"><span><br></span></pre>
<span id="HUD" style="opacity:0">
<div id="gui_stats" class="noselect">
FPS : <span name="current_framerate" precision="0"></span><br>
(<span name="current_pos_x_adj" precision="2"></span>,<span name="current_pos_y_adj" precision="2"></span>)<br>
<!--(<span name="current_angle_x" precision="2"></span>,<span name="current_angle_y" precision="2"></span>)<br>-->
<!--Vel: <span name="player_speed" precision="1"></span><br>-->
<!--Time: <span name="current_time" precision="1"></span><br>-->
F:<span name="dist_to_impact_front" precision="2"></span><br>
F:<span name="time_to_impact_front" precision="2"></span>s<br>
L:<span name="dist_to_impact_left" precision="2"></span><br>
L:<span name="time_to_impact_left" precision="2"></span>s<br>
R:<span name="dist_to_impact_right" precision="2"></span><br>
R:<span name="time_to_impact_right" precision="2"></span>s<br>
<canvas id="canvas" style="position:absolute;right:0;width:200px;" ></canvas>
</div>
<div id="game_stats" class="noselect" style="opacity:0">
<div style="color:white;position:fixed;bottom:4px;left:0;right:0">
<div style="text-align:center">
0
<div class="notprogressbar" style="text-align:center;position:absolute">
<span name="player_speed" toprecision=2></span>
</div>
<div class="progressbar">
<div name="player_speed" class="progress" style="background:white"></div>
</div>
<span name="max_speed" precision=2></span>
<div style="text-align:center">Speed</div>
</div>
</div>
<div style="color:white;position:fixed;bottom:4px;left:1%">
0
<div class="progressbar" style="text-align:center">
<div name="player_rubber" class="progress" bgcolorgrad="0,15,0;15,0,0"></div>
</div>
<span name="cycle_rubber" toprecision=1></span>
<div style="text-align:center"><span name="player_rubber" precision=1 toprecision=2></span></div>
</div>
<div style="color:white;position:fixed;bottom:4px;right:1%">
0
<div class="progressbar" style="text-align:center">
<div name="player_brake" class="progress" bgcolorgrad="15,0,0;0,15,0"></div>
</div>
1
<div style="text-align:center">Brake</span></div>
</div>
</div>
<div id="scoreboard">
<table style="width:100%">
<thead>
<tr><th>&nbsp;<span style="color:#f80">Name:</span></th><th>Alive:</th><th>Score:</th><th>Ping:</th><th>Team:</th></tr>
</thead>
<tbody>
<!--<tr><td>&nbsp;Test</td><td>huh</td><td>0</td><td>0</td><tr>-->
</tbody>
</table>
</div>
</span>
<div id="centerMessage">&nbsp;</div>
<script type="text/javascript" src="scripts/input.js"></script>
<script type="text/javascript" src="scripts/menu.js"></script>
<script type="text/javascript" src="scripts/config.js"></script><!-- configuration + local storage -->
<script type="text/javascript" src="scripts/zone.js"></script>
<script type="text/javascript" src="scripts/player.js"></script>
<script type="text/javascript" src="scripts/team.js"></script>
<script type="text/javascript" src="scripts/ai.js"></script>
<script type="text/javascript" src="scripts/functions-body.js"></script><!-- body functions -->
<script type="text/javascript" src="scripts/buildObjects.js"></script><!-- builds usable scene objects -->
<script type="text/javascript" src="scripts/init.js"></script><!-- initializes render -->
<script type="text/javascript" src="scripts/game.js"></script><!-- game -->
<script type="text/javascript" src="scripts/render.js"></script><!-- render loop functions -->
<script type="text/javascript" src="scripts/network.js"></script><!-- network test -->
</body>
</html>
diff --git a/layout/menu.xml b/layout/menu.xml
index 2de20b6..da83f08 100644
--- a/layout/menu.xml
+++ b/layout/menu.xml
@@ -1,314 +1,315 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Menus>
<Menu id="firsttime" title="Welcome to @progtitle@!
&lt;div style='font-size:17pt'>Please choose some initial settings:&lt;/div>">
<Item type="list" call="init_key" text="Keyset">
<Option value="-1" text="Don't Touch!" />
<Option value="0" text="Home row" /> <!--(ASDF for left and JKL; for right)-->
<Option value="1" text="WASD/Arrows" />
</Item>
<Item type="list" call="init_color" text="Initial Color">
<Option value="0" text="0xff0000Red" />
<Option value="1" text="0xff8800Orange" />
<Option value="2" text="0xffff00Yellow" />
<Option value="3" text="0x00ff00Green" />
<Option value="4" text="0x00ffffCyan" />
<Option value="5" text="0x0000ffBlue" />
<Option value="6" text="0xff00ffViolet" />
</Item>
<Item type="str" var="player.name" text="Name"/>
<Item type="exitmenu" text="Let's go!"/>
</Menu>
<Menu id="main" title="@progtitle@ Alpha">
<Item type="submenu" onenter="game" text="Play"/>
<Item type="submenu" onenter="player" text="Customize Player"/>
<Item type="submenu" onenter="input" text="Configure Input"/>
<Item type="submenu" onenter="system" text="Configure 3DCycles"/>
<Item type="submenu" onenter="about" text="About"/>
<!-- <Item type="submenu" onenter="egg" text="&lt;- Go Back"/> -->
<!-- alt: <Item type="text" text="" /> <!- - no exit game function, escape will do nothing -->
<Item type="js" onenter="menu('quit')" text="Quit"/>
</Menu>
<!-- General game configuration -->
<Menu id="game" title="Play Game">
<Item type="js" onenter="playGame()" style="display:inline-block;" text="Locally"/>
<Item type="submenu" onenter="game_setup" style="font-size:16pt;" text="(config)"/>
<Item type="submenu" onenter="network" text="Network"/>
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="network" title="Network Game">
<Item type="str" var="CONNECT_HOST" text="Host" />
<Item type="num" range="1024,49151" var="CONNECT_PORT" text="Port" />
<Item type="list" var="CONNECT_SSL" text="SSL">
<Option value="false" text="No" /> <Option value="true" text="Yes" />
</Item>
<Item type="js" onenter="connectToGame()" text="Connect"/>
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="game_setup" title="Local Game Config" if="not engine.network">
<Item type="submenu" onenter="presets" text="Load Preset..."/>
<Item type="num" range="0,Infinity" var="TEAMS_MIN" text="Min Teams (# of Humans+AIs)" />
<Item type="list" var="GAME_TYPE" text="When the round finishes">
<Option value="0" text="Keep the round going" />
<Option value="1" text="End the round" />
</Item>
<Item type="list" var="FINISH_TYPE" text="When only AIs remain">
<Option value="1" text="Have AIs win" />
<Option value="2" text="Fast finish" />
<Option value="3" text="Find winner (alpha)" />
</Item>
<Item type="num" range="-20,15" var="SIZE_FACTOR" text="Arena Size" />
<Item type="num" range="0,Infinity" var="CYCLE_SPEED" text="Cycle Speed" />
<Item type="num" range="0,Infinity" var="CYCLE_RUBBER" text="Cycle Rubber" />
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<!--<Menu id="presets" title="Load Preset">
<Item type="js" onenter="preset('classic');menu('exitmenu');menu('exitmenu')" text="Classic"/>
<Item type="js" onenter="preset('df');menu('menu:loading')" text="Dogfight"/>
<Item type="js" onenter="preset('hr');menu('menu:loading')" text="High Rubber"/>
<Item type="js" onenter="preset('ft');menu('menu:loading')" text="Fast Track"/>
<Item type="js" onenter="preset('fort');menu('menu:loading')" text="Fortress"/>
<Item type="js" onenter="preset('racing');menu('menu:loading')" text="Racing"/>
<Item type="js" onenter="preset('zonetest');menu('exitmenu');menu('exitmenu')" text="Zone test"/>
<Item type="exitmenu" text="Cancel"/>
</Menu>-->
<Menu id="presets" title="Load Preset">
<Item type="js" style="font-size:14pt" onenter="preset('classic');menu('exitmenu');menu('exitmenu')"
text="Classic" title="Default low rubber settings in Armagetron"/>
<Item type="js" style="font-size:14pt" onenter="menu('menu:loading');preset('df')"
text="Loose Dogfight" title="Obey loose dogfight rules or go elsewhere!"/>
<Item type="js" style="font-size:14pt" onenter="menu('menu:loading');preset('hr')"
text="0x0000ff-=}0xffffffID0x0000ff&lt; 0xffff00T0x00ff00I0xffff00L0x00ff00T 0x0000ffHigh Rubber0x00ff00" title="No camping!"/>
<Item type="js" style="font-size:14pt" onenter="menu('menu:loading');preset('ft')"
text="0xc0c000&gt;&gt;&gt; 0xff0000F0xff1c1cA0xff3838S0xff5555T0xff7171T0xff8d8dR0xffaaaaA0xffc6c6C0xffe2e2K 0xc0c000&lt;&lt;&lt;" title="Gotta go fast! Very fast!"/>
<Item type="js" style="font-size:14pt" onenter="menu('menu:loading');preset('fort')"
text="Fortress" title="Take the enemy's base, try not to let them take yours."/>
<Item type="js" style="font-size:14pt" onenter="menu('menu:loading');preset('styball')"
text="Styball (Soccer / Hockey)" title="Push the ball into the enemy's base, but don't let them push it into yours!"/>
<Item type="js" style="font-size:14pt" onenter="menu('menu:loading');preset('racing')"
text="0x66cc66Adventures of 0x00cc00TRON 0xffffff>> Advanced Racing &lt;&lt;" title="First to the finish line wins!"/>
<Item type="js" style="font-size:14pt" onenter="menu('menu:loading');preset('snake')"
text="0x66ccffSnake Survival" title="How long can you get your trail?"/>
<Item type="js" style="font-size:14pt" onenter="preset('zonetest');menu('exitmenu');menu('exitmenu')"
text="Zone test" title="Zones! Zones! Zones! Zones everywhere!"/>
<Item type="exitmenu" text="Cancel" title="Never mind, none of these look interesting..."/>
</Menu>
<Menu id="loading" title="Loading...">
<Item type="text" text="" from="con:last" style="font-size:14pt;text-align:left;padding:10px;color:grey" />
</Menu>
<!-- Player configuration -->
<Menu id="player" title="Player Setup">
<Item type="str" var="player.name" text="Name"/>
<Item type="submenu" onenter="macro" text="Instant Chats"/>
<Item type="color" var="player.cycleColor" text="Cycle Color" />
<Item type="color" var="player.tailColor" text="Tail Color" />
<!--<Item type="num" range="0,5" var="player.engineType" text="Engine Type" />-->
<Item type="list" var="player.spectating" text="Spectator Mode">
<Option value="false" text="Off" /> <Option value="true" text="On" />
</Item>
<Item type="js" onenter="exportUsrSets()" text="Export player settings" />
<Item type="js" onenter="importSets()" text="Import settings" />
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="macro" title="Instant Chats">
<!--<Foreach var="instantchats" as="n">
<Item type="str" var="instantchats.$(n).text" text="Chat"/>
<Item type="keys" var="instantchats.$(n).input" text="Input" />
<Item type="text" text="&amp;nbsp;" />
</Foreach>-->
<Item type="str" var="instantchats.0.text" text="Chat"/>
<Item type="keys" var="instantchats.0.input" text="Input" />
<Item type="text" text="&amp;nbsp;" />
<Item type="str" var="instantchats.1.text" text="Chat"/>
<Item type="keys" var="instantchats.1.input" text="Input" />
<Item type="text" text="&amp;nbsp;" />
<Item type="str" var="instantchats.2.text" text="Chat"/>
<Item type="keys" var="instantchats.2.input" text="Input" />
<Item type="text" text="&amp;nbsp;" />
<Item type="str" var="instantchats.3.text" text="Chat"/>
<Item type="keys" var="instantchats.3.input" text="Input" />
<Item type="text" text="&amp;nbsp;" />
<Item type="js" onenter="" text="Add instant chat (future)" />
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="input" title="Configure Input">
<Item type="submenu" onenter="input_conf" text="Player Control"/>
<Item type="submenu" onenter="global_input_conf" text="Global Input"/>
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="input_conf" title="Player Input">
<Item type="keys" var="left" text="Turn left" />
<Item type="keys" var="right" text="Turn right" />
<!--<Item type="keys" var="north" text="Turn North" />
<Item type="keys" var="south" text="Turn South" />
<Item type="keys" var="east" text="Turn East" />
<Item type="keys" var="west" text="Turn West" />-->
<Item type="keys" var="boost" text="Boost" />
<Item type="keys" var="toggleboost" text="Toggle Boost" />
<Item type="keys" var="brake" text="Brake" />
<Item type="keys" var="togglebrake" text="Toggle Brake" />
<Item type="keys" var="jump" text="Jump" />
<Item type="keys" var="chat" text="Chat" />
<Item type="keys" var="camera" text="Switch View" />
<Item type="keys" var="look_left" text="Look Left" />
<Item type="keys" var="look_right" text="Look Right" />
<Item type="keys" var="look_forward" text="Look Forward" />
<Item type="keys" var="look_back" text="Look Back" />
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<!-- Configuration -->
<Menu id="system" title="System Setup">
<Item type="submenu" onenter="screen" text="Configure Display"/>
<Item type="submenu" onenter="display" text="Configure Visuals"/>
<Item type="submenu" onenter="sound" text="Configure the Sound"/>
<Item type="submenu" onenter="other" text="Misc Settings"/>
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="screen" title="Screen Mode">
<Item type="list" call="settings.FULLSCREEN" text="Fullscreen (F11)" title="It's recommended that you use F11 instead of this fullscreen option. It is, however, left in for mobile touchscreen devices.">
<Option value="false" text="Off" /> <Option value="true" text="On" />
</Item>
<Item type="list" var="REDRAW_MODE" text="VSync" title="Synchronize framerate with vertical refresh rate\nThe vertical refresh rate is basically the frames per second your monitor displays. Turning this on would make it depend on browser redraw calls, effectively capping your FPS at the refresh rate. Turning it off would continously draw the frames but throws away additional frames that your monitor doesn't display. Depending on game loop configuration, this can provide minimal advantage.">
<Option value="1" text="Off" /> <Option value="0" text="On" />
</Item>
<Item type="num" range="1,Infinity" var="MAX_TARGET_FPS" text="Max Target FPS" />
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="display" title="Visual Settings">
<Item type="submenu" onenter="detail" text="Detail Settings"/>
<Item type="submenu" onenter="visual_prefs" text="Other Preferences"/>
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="detail" title="Detail Settings">
<Item type="list" call="aamenurender" text="Menu Background Rendering" title="How the background is rendered. Default: Image">
<Option value="img" text="Image" />
<Option value="css" text="CSS" />
<Option value="css_rot" text="CSS+Rotation" />
</Item>
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="visual_prefs" title="Preferences">
<Item type="list" var="HIGH_RIM" text="High Rims">
<Option value="false" text="Off" /> <Option value="true" text="On" />
</Item>
<Item type="list" var="EXPLOSION" text="Explosions">
<Option value="false" text="Off" /> <Option value="true" text="On" />
</Item>
<Item type="list" var="engine.view" from="engine.views" text="Current Camera" />
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="sound" title="Sound Configuration">
<Item type="list" var="player.engineType" text="Sound set">
<Option value="5" text="ArmagetronAd" />
<Option value="3" text="Tr2n Origins" />
<Option value="4" text="glTron" />
</Item>
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="other" title="Misc Configuration">
<Item type="submenu" onenter="display_tweaks" text="Tweaks"/>
<Item type="submenu" onenter="global_input_conf" text="Global Keys"/>
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="display_tweaks" title="Game Tweaks">
<Item type="list" var="GAME_LOOP" text="Run game loop">
<Option value="0" text="Outside render cycle" />
<Option value="2" text="Outside+during render cycle" title="possibily reduces fps?" />
<Option value="0.5" text="Outside render cycle + cycle movement in render" title="may reduce visible jumps, the default" />
<Option value="1" text="During render cycle" title="may reduce jumps but increase lag"/>
</Item>
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="global_input_conf" title="Input Configuration">
<Item type="keys" var="scroll_up" text="Scroll Up" />
<Item type="keys" var="scroll_down" text="Scroll Down" />
<Item type="keys" var="scroll_end" text="Scroll to End" />
<Item type="keys" var="score" text="Toggle Scoreboard" />
+ <Item type="keys" var="esc" text="In-game Menu" />
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="about" title="About">
<Item type="text" style="font-size:15pt" text="0xff8800Title: 0xRESETT@progtitle@" />
<Item type="text" style="font-size:15pt" text="Draws heavy inspiration from the excellent lightcycle game Armagetron Advanced." />
<Item type="text" style="font-size:15pt" text="0xff8800Version: 0xRESETTv1.0-beta6" />
<Item type="text" style="font-size:15pt" text="This is a development version. It's a heavy work in progress. Anything could change at any time, and there may be a lot of bugs." />
<Item type="submenu" onenter="about_dev" text="Credits"/>
<Item type="submenu" onenter="license" text="Legal Stuff"/>
<!--<Item type="text" text="0xff7f00Official Website: 0xRESETTN/A" />-->
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="about_dev" title="Credits">
<Item type="text" style="font-size:15pt" text="0xff8800Project Admin: 0xRESETTNelg" />
<Item type="text" style="font-size:15pt" text="0xff8800Developers: 0xRESETTNelg, Durf" />
<Item type="text" style="font-size:15pt" text="0xff8800Collision Detection: 0xRESETTDurf, softSurfer" />
<Item type="text" style="font-size:15pt" text="0xff8800ArmagetronAd Font: 0xRESETTLucifer, Fabrice Holbe" />
<Item type="text" style="font-size:15pt" text="0xRESETTDefault Theme:" />
<Item type="text" style="font-size:15pt" text="0xff8800Wall Textures: 0xRESETTBrian Hilmers" />
<Item type="text" style="font-size:15pt" text="0xff8800Textures: 0xRESETTthe Armagetron Advanced development team" />
<Item type="text" style="font-size:15pt" text="0xff8800ArmagetronAd Cycles: 0xRESETTZ-Man(?)" />
<!--<Item type="text" style="font-size:15pt" text="0xff8800Testing: 0xRESETTdukevin, light, jericho, zoom" />-->
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="license" title="Legal Stuff">
<Item type="text" style="font-size:15pt" text="3DCycles - A lightcycle game. &lt;br>
Copyright (C) 2019 Glen Harpring &lt;br> &lt;br>
This program is free software; you can redistribute it and/or &lt;br>
modify it under the terms of the GNU General Public License &lt;br>
as published by the Free Software Foundation; either version 2 &lt;br>
of the License, or (at your option) any later version. &lt;br>
&lt;br>
This program is distributed in the hope that it will be useful, &lt;br>
but WITHOUT ANY WARRANTY; without even the implied warranty of &lt;br>
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the &lt;br>
GNU General Public License for more details. &lt;br>
&lt;br>
You should have received a copy of the GNU General Public License &lt;br>
along with this program; if not, write to the Free Software &lt;br>
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA." />
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="pause" title="Paused" exitmenu="pauseMenuToggle()">
<Item type="submenu" onenter="game_setup" text="Local Game Setup"/>
<Item type="submenu" onenter="team" text="Change Teams"/>
<Item type="submenu" onenter="player" text="Customize Player"/>
<Item type="submenu" onenter="input" text="Configure Input"/>
<Item type="submenu" onenter="system" text="Configure 3DCycles"/>
<Item type="submenu" onenter="about" text="About"/>
<Item type="leave" text="Leave Grid"/>
<Item type="exitmenu" text="Return to Game"/>
</Menu>
<Menu id="team" title="Change Teams">
<!-- script to dynamically generate items-->
<Item type="list" var="player.spectating" text="Spectator Mode" onenter="KILL_ALL">
<Option value="false" text="Off" /> <Option value="true" text="On" />
</Item>
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="vote" title="Vote" exitmenu="menu('exitmenu');vote(voteopt)"> <!--Future implementation?-->
<Item type="list" call="function(in){voteopt = in; return '';}" text="Vote">
<Option value="no" text=" No &gt;" />
<Option value="" text="&lt; Ignore &gt;" />
<Option value="yes" text="&lt; Yes " />
</Item>
<Item type="exitmenu" text="Submit"/>
</Menu>
<Menu id="highscores" title="0x000000Highscores">
<Item type="text" text="0xff0000»0x808080Swag´0xRESETT: INF points" />
<Item type="text" text="0x0088ff|0xRESETTNelg0xRESETT: 10 points" />
<Item type="text" text="0x00ff00Z-Man0xRESETT: 1 points" />
<Item type="exitmenu" text="&lt;- Go Back"/>
</Menu>
<Menu id="preset_loaded" title="Preset Loaded">
<Item type="js" onenter="playGame()" text="Play"/>
<Item type="submenu" onenter="input_conf" text="Set Controls"/>
<Item type="exitmenu" text="Back to main menu"/>
</Menu>
</Menus>
diff --git a/scripts/input.js b/scripts/input.js
index 5c3ace9..52e9efd 100644
--- a/scripts/input.js
+++ b/scripts/input.js
@@ -1,501 +1,501 @@
/*
* 3DCycles - A lightcycle game.
* Copyright (C) 2019 Glen Harpring
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
function stopPropagation(e)
{
e = e || event;/* get IE event ( not passed ) */
e.stopPropagation? e.stopPropagation() : e.cancelBubble = true;
e.returnValue = false;
}
//EVENT INPUTS
var keyboardKeyDown = function(e)
{
e = e || event;//safety (against what?)
//get state here, like: playing, menu, chatting, etc.
//refer to engine.inputState: menu | menu2 | game | chat | pause
//for each input state, either switch(keyCode) {}, or send keycode to appropriate function
var keyCode = typeof(keyCodeRemap[e.keyCode]) == "undefined"?e.keyCode:keyCodeRemap[e.keyCode];
var specificState = engine.inputState.split(':');
if(specificState[0] != "input" && settings.controls.console.indexOf(keyCode) > -1) //console key works everywhere except other inputs
{
var input = document.getElementById("input");
input.style.display = "block";
engine.inputStatePrev = engine.inputState;
engine.inputState = "input:console";
if(engine.players[engine.activePlayer]) engine.players[engine.activePlayer].chatting = true;
updateScoreBoard();
input.children[0].innerText = "Con:";
input.children[1].focus();
stopPropagation(e);
}
else if(specificState[0] == 'menu'/* || engine.paused*/) //any menu, not game
{
var actmenu = document.getElementsByClassName("menu-active")[0];
if(!actmenu)
{
if(engine.menus.length == 1) menu("menu:"+engine.menus[engine.menus.length-1]);
else if(engine.menus.length > 1) menu("exitmenu");
else menu("menu:main");
return;
}
if(actmenu.attributes.id)
actid = actmenu.attributes.id.value;
else
actid = "";
var actsp = actid.split(":");
/*if(actsp[0] != "var" && (actsp[2] != "str" || actsp[2] == "color"))
stopPropagation(e);*/
//console.log(actid.split(":"));
switch(keyCode)
{
case 13: //enter
//menuSelect('enter',"key");
break;
case 27: //esc
stopPropagation(e);
menuSelect('esc',"key");
break;
case 37: //left
menuSelect('left',"key");
break;
case 38: //up
menuSelect('up',"key");
break;
case 39: //right
menuSelect('right',"key");
break;
case 40: //down
menuSelect('down',"key");
break;
}
}
else if(specificState[0] == 'input')
{
switch(keyCode)
{
case 9: //tab
var input = document.getElementById("input");
var textbox = input.children[1];
var output = textbox.value;
var split = output.split(" ");
if(specificState[1] == "console")
{
}
else switch(split[0])
{
case "/console":
split[split.length-1]
break;
default:
var p = getPlayer(split[split.length-1]);
if(p)
{
//textbox.value += p.getColoredName();
split[split.length-1] = p.getColoredName()+"0xffff7f";
if(split.length == 1) split[split.length-1] += ", ";
else split[split.length-1] += " ";
textbox.value = split.join(" ");
}
else
{
engine.console.print("Matches:\n");
for(var i=engine.players.length;i--;)
{
if(engine.players[i].name.toLowerCase().indexOf(name.toLowerCase()) > -1)
{
engine.console.print(engine.players[i].name+"\n");
}
}
}
break;
}
stopPropagation(e);
break;
case 27: case 13: //escape or return
var input = document.getElementById("input");
var textbox = input.children[1];
var output = textbox.value; textbox.value = "";
input.style.display = "none";
if(engine.players[engine.activePlayer]) engine.players[engine.activePlayer].chatting = false;
engine.inputState = engine.inputStatePrev;
updateScoreBoard();
if(keyCode == 13) //return
{
switch(specificState[1])
{
case "chat":
handleChat(engine.players[engine.activePlayer],output);
break;
case "console":
engine.console.print("0x7f7fff> "+output+"\n");
loadcfg(output);
break;
}
//engine.inputState = engine.inputStatePrev;
}
break;
}
}
else if(engine.inputState == 'game') //game settings.controls
{
gameControl(keyCode);//send keycode to control function
//if(engine.inputState.split(':')[0] == "input" || keyCode == 9)
stopPropagation(e);
}
else //parse input state (typically settings to add/remove controls)
{
if(specificState[0] == 'controlAR')
{
stopPropagation(e);
- if(e.keyCode == 27)
+ if(!e.forceHACK && e.keyCode == 27)
{
engine.inputState = "menu:"+engine.menus[engine.menus.length-1]; menu("reload");
return;
}
var temp_items = Object.keys(settings.controls);
var temp_item = temp_items.indexOf(specificState[1]) || 0;
if(settings.controls[specificState[1]].indexOf(keyCode) > -1) //control is there already
{
settings.controls[specificState[1]].splice(settings.controls[specificState[1]].indexOf(keyCode), 1); //remove
}
else
{
for(var i=0;i<temp_items.length;i++)
{
control = temp_items[i];
//check existing controls and clear other instances of the new control
if(control != specificState[1])
{
if(settings.controls[control].indexOf(keyCode) > -1)
{
settings.controls[control].splice(settings.controls[control].indexOf(keyCode),1); //remove control found
}
}
}
settings.controls[specificState[1]].push(keyCode); //add control to chosen option
settings.controls[specificState[1]].sort(function(a,b){return a-b});//sort listing in order
}
engine.inputState = "menu:"+engine.menus[engine.menus.length-1]; menu("reload");
//menu('menu-controls_'+temp_item);
}
}
}
var keyboardKeyUp = function(e)
{
if(engine.inputState == 'game')//game settings.controls
{
gameControlUp(typeof(keyCodeRemap[e.keyCode]) == "undefined"?e.keyCode:keyCodeRemap[e.keyCode]);
}
}
//GAME
function touchControl(e)
{
if(!document.oncontextmenu)
document.oncontextmenu = function(){return false}
if(engine.inputState == 'game')
{
//console.log(e);
var sepX = document.body.offsetWidth/3, sepY = document.body.offsetHeight/2;
if(engine.gtime > 0)
{
/*engine.console.print(e.touches.length+" touches");
for(var x=e.touches.length-1;x>=0;x--)*/
var x = 0; //other touch appears to get sent in another message anyway
{
//var dir = (e.touches[x].clientX < half)?-1:1;
if(e.touches[x].clientX > sepX*2)
{
var dir = 1;
}
else if(e.touches[x].clientX > sepX)
{
if(e.touches[x].clientY < sepY)
{
engine.players[engine.activePlayer].boosting = !engine.players[engine.activePlayer].boosting;
}
else
{
engine.players[engine.activePlayer].braking = !engine.players[engine.activePlayer].braking;
}
return;
}
else
{
var dir = -1;
}
if(engine.players[engine.activePlayer].alive)
engine.players[engine.activePlayer].turn(dir);
else if(engine.players[engine.activePlayer].dedtime+1000 > performance.now())
changeViewTarget(dir);
}
}
}
}
//game settings.controls - keydown
function gameControl(keycode)
{
if(engine.controls.pressed.indexOf(keycode) == -1)
{
if(engine.gtime > 0)
{
if(settings.controls.left.indexOf(keycode) > -1)
{
if(engine.players[engine.activePlayer].alive)
engine.players[engine.activePlayer].turn(-1);
else if(engine.players[engine.activePlayer].dedtime+1000 < performance.now())
changeViewTarget(-1);
engine.controls.pressed.push(keycode);
}
if(settings.controls.right.indexOf(keycode) > -1)
{
if(engine.players[engine.activePlayer].alive)
engine.players[engine.activePlayer].turn(1);
else if(engine.players[engine.activePlayer].dedtime+1000 < performance.now())
changeViewTarget(1);
engine.controls.pressed.push(keycode);
}
if(settings.controls.north.indexOf(keycode) > -1)
{
if(engine.players[engine.activePlayer].alive)
engine.players[engine.activePlayer].turnAbs(0,1);
}
if(settings.controls.south.indexOf(keycode) > -1)
{
if(engine.players[engine.activePlayer].alive)
engine.players[engine.activePlayer].turnAbs(0,-1);
}
if(settings.controls.east.indexOf(keycode) > -1)
{
if(engine.players[engine.activePlayer].alive)
engine.players[engine.activePlayer].turnAbs(1,0);
}
if(settings.controls.west.indexOf(keycode) > -1)
{
if(engine.players[engine.activePlayer].alive)
engine.players[engine.activePlayer].turnAbs(-1,0);
}
if(settings.controls.togglebrake.indexOf(keycode) > -1)
{
if(engine.players[engine.activePlayer].alive)
engine.players[engine.activePlayer].braking = !engine.players[engine.activePlayer].braking;
engine.controls.pressed.push(keycode);
}
if(settings.controls.brake.indexOf(keycode) > -1)
{
if(engine.players[engine.activePlayer].alive)
engine.players[engine.activePlayer].braking = true;
engine.controls.pressed.push(keycode);
}
if(settings.controls.boost.indexOf(keycode) > -1)
{
if(engine.players[engine.activePlayer].alive)
{
if(settings.CYCLE_BOOST == 0 && settings.CYCLE_BRAKE < 0)
engine.players[engine.activePlayer].braking = true;
else
engine.players[engine.activePlayer].boosting = true;
}
engine.controls.pressed.push(keycode);
}
if(settings.controls.jump.indexOf(keycode) > -1)
{
if(settings.CYCLE_MIDAIR_JUMP || engine.players[engine.activePlayer].position.z == 0)
engine.players[engine.activePlayer].model.rotation.y = -settings.CYCLE_JUMP;
engine.controls.pressed.push(keycode);
}
}
if(settings.controls.look_left.indexOf(keycode) > -1)
{
engine.camera.userViewDir = engine.players[engine.viewTarget].left;
engine.controls.pressed.push(keycode);
}
if(settings.controls.look_right.indexOf(keycode) > -1)
{
engine.camera.userViewDir = engine.players[engine.viewTarget].right;
engine.controls.pressed.push(keycode);
}
if(settings.controls.look_forward.indexOf(keycode) > -1)
{
engine.camera.userViewDir = cdir(engine.players[engine.viewTarget].rotation.z);
engine.controls.pressed.push(keycode);
}
if(settings.controls.look_back.indexOf(keycode) > -1)
{
engine.camera.userViewDir = cdir(engine.players[engine.viewTarget].rotation.z-Math.PI);
engine.controls.pressed.push(keycode);
}
}
if(settings.controls.chat.indexOf(keycode) > -1)
{
var input = document.getElementById("input");
input.style.display = "block";
engine.inputStatePrev = engine.inputState;
engine.inputState = "input:chat";
engine.players[engine.activePlayer].chatting = true;
updateScoreBoard();
input.children[0].innerText = "Say:";
input.children[1].focus();
}
if ( settings.controls.camera.indexOf(keycode) > -1 ) {
//do camera change
if ( engine.controls.pressed.indexOf(keycode) == -1 ) { //if not pressed, CHANGE
if (engine.views.indexOf(engine.view) == (engine.views.length-1) ) { //if is last view in list, go back to first [0]
engine.view = engine.views[0];
}
else {//change UP in list
engine.view = engine.views[((engine.views.indexOf(engine.view)) + 1)];
}
engine.controls.pressed.push(keycode);//add only if not added already to pressed keys
}
if(engine.view == 'cockpit')
engine.players[engine.viewTarget].audio.gain.setTargetAtTime(0.2, ctx.currentTime, 0.02);
else
engine.players[engine.viewTarget].audio.gain.setTargetAtTime(6, ctx.currentTime, 1);
console.log('CHANGE_CAMERA to '+engine.view);
}
if(settings.controls.score.indexOf(keycode) > -1)
{
var scoreboard = document.getElementById("scoreboard");
scoreboard.style.display = scoreboard.style.display=="none"?"block":"none";
updateScoreBoard();
}
if(settings.controls.esc.indexOf(keycode) > -1)
{
//do in game menu
if(!engine.paused) pauseMenuToggle();
}
if(settings.controls.scroll_up.indexOf(keycode) > -1)
{
engine.console.scroll(-10);
engine.console.time_manual = performance.now();
}
if(settings.controls.scroll_down.indexOf(keycode) > -1)
{
engine.console.scroll(10);
engine.console.time_manual = performance.now();
}
if(settings.controls.scroll_end.indexOf(keycode) > -1)
{
if(settings.TEXT_OUT_MODE == 1)
{
var lines = engine.console.scrollback
var lnnum = engine.console.scrollby;
var currln = lines[lnnum];
}
else
{
var lines = engine.console.innerText.split("\n");
var lnnum = (-(parseFloat(engine.console.style.top)/engine.console.scrollby));
var currln = lines[lnnum-1];
}
engine.console.time_manual = 0;
engine.console.scroll(lines.length-lnnum-1);
}
if(settings.controls.pause.indexOf(keycode) > -1)
{
console.log('PAUSE');//do pause
}
for(var x=settings.instantchats.length-1;x>=0;--x)
{
var chat = settings.instantchats[x];
for(var y=chat.input.length-1;y>=0;--y)
{
if(keycode == chat.input[y]) handleChat(engine.players[engine.activePlayer],chat.text);
}
}
}
//keyup
function gameControlUp(keycode)
{
if(engine.controls.pressed.indexOf(keycode) > -1)
{
var temp = engine.controls.pressed.indexOf(keycode);
if ( temp > -1 ) //if is pressed
engine.controls.pressed.splice(temp, 1);
}
if(settings.controls.brake.indexOf(keycode) > -1)
{
engine.players[engine.activePlayer].braking = false;
}
if(settings.controls.boost.indexOf(keycode) > -1 )
{
if(settings.CYCLE_BOOST == 0 && settings.CYCLE_BRAKE < 0)
engine.players[engine.activePlayer].braking = false;
engine.players[engine.activePlayer].boosting = false;
}
if(
settings.controls.look_left.indexOf(keycode) > -1 ||
settings.controls.look_right.indexOf(keycode) > -1 ||
settings.controls.look_forward.indexOf(keycode) > -1 ||
settings.controls.look_back.indexOf(keycode) > -1
)
{
engine.camera.userViewDir = false;
}
}
var keyCodeRemap = { 59:186, 61:187 }; //some browsers used alternate keycodes for ; and =
var keycodeList = {
8: 'Backspace',
13: 'Enter',
16: 'Shift', 20: 'Capslock',
17: 'Ctrl', 18: 'Alt',
19: 'Pause/Break', 27: 'Escape', 93: 'Menu',
9: 'Tab', 32: 'Spacebar',
33: 'Page Up',34: 'Page Down',
36: 'Home', 35: 'End',
37: 'Left Arrow', 39: 'Right Arrow',
38: 'Up Arrow', 40: 'Down Arrow',
45: 'Insert', 46: 'Delete',
48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5', 4: '6', 55: '7', 56: '8', 57: '9',
65: 'A', 66: 'B', 67: 'C', 68: 'D', 69: 'E', 70: 'F', 71: 'G', 72: 'H', 73: 'I', 74: 'J', 75: 'K', 76: 'L', 77: 'M', 78: 'N', 79: 'O', 80: 'P', 81: 'Q', 82: 'R', 83: 'S', 84: 'T', 85: 'U', 86: 'V', 87: 'W', 88: 'X', 89: 'Y', 90: 'Z',
91: 'Left Meta', 92: 'Right Meta',
111: 'NUM /', 106: 'NUM *', 109: 'NUM -', 107: 'NUM +', 110: 'NUM .',
96: 'NUM 0', 97: 'NUM 1', 98: 'NUM 2', 99: 'NUM 3', 100: 'NUM 4', 101: 'NUM 5', 102: 'NUM 6', 103: 'NUM 7', 104: 'NUM 8', 105: 'NUM 9',
112: 'F1', 113: 'F2', 114: 'F3', 115: 'F4', 116: 'F5', 117: 'F6', 118: 'F7', 119: 'F8', 120: 'F9', 121: 'F10', 122: 'F11', 123: 'F12',
144: 'Num Lock', 145: 'Scroll Lock',
186: ';',
187: '=',
188: ',',
189: '-',
190: '.',
191: '/',
192: '`',
219: '[', 221: ']',
220: '\\',
222: '\'',
};
diff --git a/scripts/menu.js b/scripts/menu.js
index 8773f8a..dbb72c4 100644
--- a/scripts/menu.js
+++ b/scripts/menu.js
@@ -1,457 +1,459 @@
/*
* 3DCycles - A lightcycle game.
* Copyright (C) 2019 Glen Harpring
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//change setting via keyboard (menuselect left or right)
function changeMenuItem(name,add,wrap=false,from=false,ref=false)
{
var actmenu = document.getElementsByClassName("menu-active")[0];
var actsp = name.split(":");
//console.log(actsp);
if(actsp[0] == "list")
{
var elem = actmenu.children[0].children[1];
var keys = Object.keys(elem.options);
var elempos = -1;
for(i=0;i<keys.length;i++)
{
if(elem.options[keys[i]] == elem.innerText)
{
elempos = i; break;
}
}
elempos += add;
if(elempos >= keys.length) if(wrap) elempos = 0; else elempos = keys.length-1;
if(elempos < 0) if(wrap) elempos = key.length-1; else elempos = 0;
elem.innerHTML = replaceColors(elem.options[keys[elempos]]);
elem.call(keys[elempos]);
}
else if(actsp[2] == "num")
{
var elem = actmenu.children[0].children[1];
var value = parseFloat(elem.innerText);
if(from != "key:enter") value += add*actmenu.add;
if(value > actmenu.max) if(wrap) value = actmenu.min; else value = actmenu.max;
if(value < actmenu.min) if(wrap) value = actmenu.max; else value = actmenu.min;
elem.innerText = value;
chsetting(actsp[1],value);
}
}
//MENU SELECT
//keyboard
function menuSelect(direction)
{
//detect menu
//if (from != 'menu-about') {//if its a screen that has a menu with options
var themenu = document.getElementById('menuList').childNodes;
//detect menu position
var selectedItem = -1;
for(var x=0;x<themenu.length;x++)
{
if(hasClass(themenu[x],'menu-active')) selectedItem = x; //find which one is selected
}
switch(direction)
{
//change menu position
case "up":
selectedItem--;
if(selectedItem < 0) selectedItem = themenu.length-1; //wrap to last item
hoverSelect(themenu[selectedItem]);
break;
case "down":
selectedItem++;
if(selectedItem >= themenu.length) selectedItem = 0; //wrap to first item
hoverSelect(themenu[selectedItem]);
break;
case "esc":
//Exit Menu should be the last item, so convenient hack
selectedItem = themenu.length-1;
//[[FALLTHROUGH]]
case "enter":
document.activeElement.blur();//remove focus from any clicked menu items
menu(themenu[selectedItem].id,"key:"+direction);
break;
//adjust setting - used to change a setting from current value, up or down some, whatever it is
case "left":
changeMenuItem(themenu[selectedItem].id,-1,false,"key:"+direction);
break;
case "right":
changeMenuItem(themenu[selectedItem].id,1,false,"key:"+direction);
break;
}
}
function menuFindPrevSelectable()
{
var themenu = document.getElementById('menuList').childNodes;
var selectedItem = -1;
for(var x=themenu.length-1;x>=0;x--)
{
if(selectedItem >= 0 && themenu[x].href)
{
return x;
}
if(hasClass(themenu[x],'menu-active')) selectedItem = x; //find which one is selected
}
return themenu.length-1;
}
function menuFindNextSelectable()
{
var themenu = document.getElementById('menuList').childNodes;
var selectedItem = -1;
for(var x=0;x<themenu.length;x++)
{
if(selectedItem >= 0 && themenu[x].href)
{
return x;
}
if(hasClass(themenu[x],'menu-active')) selectedItem = x; //find which one is selected
}
return 0;
}
function hoverSelect(item)
{
var themenu = document.getElementById('menuList').childNodes;
for(var x=0;x<themenu.length;x++)
{
if(hasClass(themenu[x],'menu-active')) themenu[x].className = '';
}
if(item.attributes.id) var stuff = item.attributes.id.value.split(":"); else var stuff = [];
if(stuff[0] != "text")
item.className = 'menu-active';
if(stuff[0] == "var")
{
var txtarea = item.childNodes[0].childNodes[1];
txtarea.focus();
//txtarea.innerText = txtarea.innerText;
}
else
{
item.childNodes[0].focus(); //to detract focus off input boxes
}
}
////////////////////////////////////////
//MENU - changes menus, performs basic actions when menu switching (pause), optional active menu element
function menu(act,from=false)
{
var selectedItem = 0, ract=act;
if(act == "exitmenu")
{
var exitmenu = "menu:"+engine.menus[engine.menus.length-1];
act = "menu:"+engine.menus[engine.menus.length-2];
engine.menus.splice(engine.menus.length-2,2);
}
else if(act == "reload")
{
act = engine.inputState;
engine.menus.splice(engine.menus.length-1,1);
var themenu = document.getElementById('menuList').childNodes;
//detect menu position
var selectedItem = -1;
for(var x=0;x<themenu.length;x++)
{
if(hasClass(themenu[x],'menu-active')) selectedItem = x; //find which one is selected
}
}
var s = act.split(":");
var action = s.shift(); //set action to first argument while removing it
var arg = s.join(":"); //and rejoin them
var split = act.split(":"); //other method
switch(action)
{
case "menu":
engine.concatch = engine.msgcatch = undefined;
+ document.getElementById("inputbuttons").style.display = "none";
document.getElementById('menu').innerHTML = "<h1>I don't know either</h1>";
var doc = engine.menu.getElementsByTagName("Menus");
if(doc.length > 0)
{
var menus = doc[0].getElementsByTagName("Menu");
for(var x=0;x<menus.length;x++)
{
var cmenu = menus[x];
if(cmenu.attributes.id.value == split[1])
{
if(cmenu.attributes.title)
document.getElementById('menu').innerHTML = "<h1>"+replaceColors(tStringify(cmenu.attributes.title.value))+"</h1>";
var items = cmenu.getElementsByTagName("Item");
var list = document.createElement("UL");
list.setAttribute("id","menuList");
for(var i=0;i<items.length;i++)
{
var item = items[i];
var parent = document.createElement("LI");
var element = document.createElement("A");
//var text = document.createTextNode(item.attributes.text.value);
var text = document.createElement("SPAN");
text.innerHTML = replaceColors(tStringify(item.attributes.text.value));
if(item.attributes.style)
{
parent.setAttribute("style",item.attributes.style.value);
}
if(item.attributes.var || item.attributes.call)
{
//text.appendData(": ");
text.append(": ");
if(item.attributes.type && item.attributes.type.value == "list")
{
parent.setAttribute("id",item.attributes.type.value);
var input = document.createElement("SPAN");
input.options = [];
if(item.attributes.call)
{
input.call = eval(item.attributes.call.value);
}
else
{
input.call = mkSettingCallback(item.attributes.var.value,true);
}
if(item.attributes.from)
{
var si = getVarFromString(item.attributes.from.value);
var subitems = si[0][si[1]];
for(var z=0;z<subitems.length;z++)
{
var option = subitems[z];
input.options[option] = option;
}
}
else
{
var subitems = item.getElementsByTagName("Option");
for(var z=0;z<subitems.length;z++)
{
var option = subitems[z];
input.options[option.attributes.value.value] = tStringify(option.attributes.text.value);
}
}
input.innerHTML = replaceColors(input.options[input.call()])
}
else if(item.attributes.type.value == "keys")
{
var input = document.createElement("SPAN");
var one = settings.controls[item.attributes.var.value];
if(!one)
{
var vri = getVarFromString(item.attributes.var.value);
one = vri[0][vri[1]];
}
var out = "";
console.log(one.length);
for(var z=0;z<one.length;z++)
{
if(z != 0) out += ", ";
out += keycodeList[one[z]];
}
if(out == "") out = "Unbound";
input.appendChild(document.createTextNode(out));
parent.setAttribute("id","controlAR:"+item.attributes.var.value);
}
else
{
parent.setAttribute("id","var:"+item.attributes.var.value+":"+item.attributes.type.value);
var input = document.createElement("SPAN");
input.setAttribute("contenteditable",true);
var vri = getVarFromString(item.attributes.var.value);
input.appendChild(document.createTextNode(vri[0][vri[1]]));
//input.setAttribute("oninput","settings."+item.attributes.var.value+" = this.innerText");
switch(item.attributes.type.value)
{
case "num":
if(item.attributes.range)
{
var spl = item.attributes.range.value.split(",");
var min = parseFloat(spl[0]), max = parseFloat(spl[1]);
}
else
{
var min = -Infinity, max = Infinity;
}
if(item.attributes.add) add = item.attributes.add.value;
else add = 1;
parent.min = min; parent.max = max; parent.add = add;
break;
case "color":
//input.style.color=input.innerText;
input.oninput = function()
{
this.style.color=this.innerText;
//this.style.background=getDarkBGFromHex(this.style.innerText);
}
input.setAttribute("onblur","this.innerText = chsetting(\""+item.attributes.var.value+"\",'#'+(new THREE.Color(this.innerText.toLowerCase()).getHexString()),true);this.oninput()");
input.className += " darktext";
input.oninput();
break;
default:
input.setAttribute("oninput","chsetting(\""+item.attributes.var.value+"\",this.innerText,true)");
break;
}
}
element.setAttribute("href","javascript:void(0);");
}
else
{
var input = false;
if(item.attributes.from)
{
var fromsplit = item.attributes.from.value.split(":");
var obj = {to:text,type:fromsplit[1]?fromsplit[1]:"all"};
switch(fromsplit[0])
{
case "con": engine.concatch = obj; break;
case "msg": engine.msgcatch = obj; break;
}
}
if(item.attributes.type.value != "text")
{
switch(item.attributes.type.value)
{
case "submenu":
parent.setAttribute("id","menu:"+item.attributes.onenter.value);
break;
case "js":
parent.setAttribute("id","js:"+item.attributes.onenter.value);
break;
case "exitmenu":
if(cmenu.attributes.exitmenu)
{
parent.setAttribute("id","js:"+cmenu.attributes.exitmenu.value);
}
else
{
//parent.setAttribute("id",engine.inputState);
parent.setAttribute("id","exitmenu");
}
break;
default:
parent.setAttribute("id",item.attributes.type.value);
break;
}
element.setAttribute("href","javascript:void(0);");
}
}
element.setAttribute("onmouseover","hoverSelect(this.parentNode)");
element.setAttribute("onclick","menu(this.parentNode.id)");
element.appendChild(text);
if(input !== false) element.appendChild(input);
parent.appendChild(element);
list.appendChild(parent);
}
engine.inputState = "menu:"+cmenu.attributes.id.value;
document.getElementById('menu').appendChild(list);
if(ract == "exitmenu") //select the menu we just left
{
var themenu = document.getElementById('menuList').childNodes;
for(var x=0;x<themenu.length;x++)
{
if(exitmenu == themenu[x].id) selectedItem = x;
}
}
hoverSelect(document.getElementById("menuList").children[selectedItem])
engine.menus.push(cmenu.attributes.id.value);
return true;
}
}
}
console.log("Menu called not found.");
break;
case "controlAR":
engine.inputState = act;
document.getElementById('menuList').getElementsByClassName("menu-active")[0].childNodes[0].childNodes[1].innerHTML = "Press a key...";
+ document.getElementById("inputbuttons").style.display = "block";
break;
case "var": case "list":
changeMenuItem(action,1,true,from,"menu")
break;
case "js":
return eval(arg);
break;
case "leave"://return to main menu from pause state
endGame(); disconnectFromGame();
engine.menus = []; menu("menu:main");
document.getElementById('menu').className = "noselect mainbg_"+settings.MENU_RENDER;
aamenurender(); showMenu();
document.title = tStringify("@progtitleshort@");
break;
case 'quit'://quit game action from any menu
window.open('','_self',''); window.close(); location.replace('about:blank');
break;
case 'unpause'://return to game from pause menu
document.getElementById('menu').style.display = 'none';
if(engine.paused) { unpauseRender(); }
engine.inputState = 'game';
break;
default:
console.log("What's this? "+action);
return false;
}
}
function pauseMenuToggle()
{
if(engine.inputState == "game")
{
if(engine.network)
{
engine.players[engine.activePlayer].chatting=true;
}
else
{
pauseRender();
}
menuSetup(true);
menu('menu:pause'); showMenu();
}
else
{
if(engine.network)
{
engine.players[engine.activePlayer].chatting=false;
}
unpauseRender();
hideMenu(); engine.inputState = 'game';
}
}
function menuSetup(game=false)
{
if(game) //ingame menu
{
document.getElementById('menu').className = "noselect pausebg";
document.getElementById('menu').style.backgroundColor = "";
}
else
{
aamenurender(); //let render selection handle it
}
}
function hideMenu()
{
document.getElementById('menu').style.display = 'none'; //hide menu
}
function showMenu()
{
document.getElementById('menu').style.display = 'block'; //show menu
}
diff --git a/styles/main.css b/styles/main.css
index 8c2d726..d2da2af 100644
--- a/styles/main.css
+++ b/styles/main.css
@@ -1,202 +1,209 @@
@font-face
{
font-family: Armagetronad;
src: url("./fonts/Armagetronad.woff");
}
@font-face
{
font-family: Flynn;
src: url("./fonts/Flynn.otf");
}
/*
@font-face
{
font-family: Minecraft;
src: url(styles/fonts/minecraft.ttf);
}
*/
@font-face
{
font-family: nicefont;
src: url(styles/fonts/nicefont.woff);
}
html, body { margin: 0; padding: 0; background:#000; overflow:hidden; font-family: Armagetronad, monospace;}
a { color: inherit; text-decoration: none; }
.noselect
{
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#menu
{
position: fixed;
width: 100%;
height: 100%;
color: #fff;
font-size: 32px;
text-align: center;
letter-spacing: 2px;
z-index: 10; /*Make sure we're on top of the game elements*/
overflow:auto;
}
#menu-tooltip
{
z-index: 15; /*We need to be on top of the menu*/
opacity: 0; display:none;
}
.menu-about
{
/*about text font size*/
font-size: 20px;
display: inline-block;
width:100%;
}
.menu-about div
{
/*about text font size*/
font-size: 20px;
display: inline-block;
}
#menu h1
{
font-size: 42px;
font-weight: normal;
}
#menuList
{
list-style: none;
list-style-type: none;
display: inline-block;
margin: 0;
padding: 0;
width: 100%;
}
#menuleft
{
display:inline-block;
width:50%;
text-align:right;
float:left;
}
#menuright
{
display:inline-block;
width:50%;
text-align:left;
}
#gui_stats
{
position: fixed;
top: 25px;
right: 25px;
color: #fff;
font-weight: bold;
font-size: 10px;
width: 69px;
overflow: visible;
}
#gui_stats div
{
width: 200px;
}
#centerMessage
{
position:absolute;
left:0; right:0;
bottom:20%;
text-align: center; color:white;
font-size: 64px;
}
#console
{
position:fixed;
background:rgba(0,0,0,0.5);
color:white;
/*max-height:30%;*/width:100%;
word-wrap: break-word;
overflow:hidden;
font-family: inherit;
font-size:12pt;
/*text-shadow: 0px 0px 10px #000;*/
}
+#inputbuttons
+{
+ position:fixed; top:0; left:0;
+ display:none;
+ z-index: 20;
+}
+
#input
{
position:fixed;
bottom: 64px;
left: 32px; right:32px;
display:none;
z-index: 20; /*We need to be on top of everything!*/
}
#input *
{
color:white; background:none;
font-family: inherit;
font-size: 22px;
}
#input input
{
width:100%; border:none;
}
#scoreboard
{
margin:auto; color:white;
display:block; position:absolute;
top:25%;left:50%;
width:500px;
margin-left:-250px;
text-shadow: 0px 0px 10px #000;
}
#scoreboard table tr
{
text-align:left;
}
.darktext
{
text-shadow: 0px 0px 10px #FFF;
}
.lighttext
{
text-shadow: 0px 0px 10px #000;
}
.progressbar, .notprogressbar
{
width:150px; height: 16px;
display:inline-block;
}
.progressbar
{
background:rgba(255,255,255,0.25);
}
.progressbar .progress
{
background:#00FF00;
height:100%;width:0%;
position:relative;
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Jun 23, 9:32 PM (3 d, 23 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
10712

Event Timeline