Skip to content

Instantly share code, notes, and snippets.

@Doohl
Last active June 1, 2016 23:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Doohl/c0e84380706e7f55b647 to your computer and use it in GitHub Desktop.
Save Doohl/c0e84380706e7f55b647 to your computer and use it in GitHub Desktop.
An example of a custom BYOND webclient. Should not be used as a working demo / example, but rather a quick reference perhaps.
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="resources/scripts/mCustomScrollbar.js"></script>
<link rel="stylesheet" href="https://raw.githubusercontent.com/malihu/malihu-custom-scrollbar-plugin/master/jquery.mCustomScrollbar.css"></link>
</head>
<body>
<div id="cover"></div>
<div id="controller" byondclass="controller"></div>
<div id="map" byondclass="map" skinparams="zoom=1"></div>
<!-- <div id="output" byondclass="output"></div> -->
<div id="chat" byondclass="chat"></div>
<div id="hotbar" byondclass="hotbar"></div>
<div id="hotbar_nums" byondclass="hotbar_nums"></div>
<div id="status" byondclass="status"></div>
<div id="hpbar" byondclass="hpbar"></div>
<div id="hpnum" byondclass="hpnum"></div>
<div id="mpbar" byondclass="mpbar"></div>
<div id="mpnum" byondclass="mpnum"></div>
</body>
macro
W return "north"
W+UP return "north-up"
North return "north"
North+UP return "north-up"
S return "south"
S+UP return "south-up"
South return "south"
South+UP return "south-up"
A return "west"
A+UP return "west-up"
D return "east"
D+UP return "east-up"
Q return "attack"
space return "dash"
F1 return "fireball"
F2 return "lightning-cloud"
F3 return "earth-spike"
F4 return "give-effect-self"
T return "say"
C return "activate-menu"
<byondclass name="controller">
<script>
(function() {
/**
Controller class that handles all logic on the client-side. Responsible for receiving and sending messages
to and from the server. Responsible for keeping track of relevant player logic.
*/
/* Container of spells in the hotbar */
var hotbar = [];
/* Fire off a spell */
var execute_spell = function(pos) {
byond.fn.topic("action=spell;slot=" + pos);
};
// The current menu
var current_menu = "statmenu";
var construct_menus = function() {
$("<div class='popup_menu' id='statmenu'></div>").appendTo("#skin").hide();
var statmenu_left_div = [
"<div class='left_pane'>",
"<div class='stat-level'>Level <div class='num lvl'>1</div></div>",
"<div class='stat-class'>Shitburgler</div>",
"<div class='char-preview'></div>",
"</div>"
].join("");
$("#statmenu").append(statmenu_left_div);
// Instantiate the rightmost div
var statmenu_right_div = [
"<div class='right_pane'>",
"<div class='stat-title'>Doohl's Stats</div>",
"<div class='stat-hp'>HP : <div class='num hp'>50/50</div></div>",
"<div class='stat-mp'>MP : <div class='num mp'>100/100</div></div>",
"<div class='stat-melee'>Melee Dmg : <div class='num mel'>1</div></div>",
"<div class='stat-magic'>Magic Dmg : <div class='num mag'>1</div></div>",
"<div class='stat-agi'>Agility : <div class='num agi'>1</div></div>",
"<div class='stat-points'>Points : <div class='num pts'>10</div></div>",
"</div>"
].join("");
$("#statmenu").append(statmenu_right_div);
};
return {
fn: {
/*
Initiate all critical functions on the client startup
*/
create: function() {
// Function to call when Jquery is initialized
function init_ui() {
// Create segments for the hotbar
for(var i = 0; i < 8; i++) {
$("#hotbar").append('<div id="spell' + (i+1) + '" class="spell" data-slot="'+ i + '" style="left: ' + (16 + i*6) + 'px"></div>');
}
/* Start defining click events */
$(".spell").click(function() {
execute_spell($(this).data("slot"));
});
// Remove the cover
$("#cover").fadeOut("slow");
// Create a scrollbar for the chat div
$.mCustomScrollbar.defaults.scrollButtons.enable=true; //enable scrolling buttons by default
$.mCustomScrollbar.defaults.axis="y"; //enable only y axis
$("#chat").mCustomScrollbar({
theme: "severed",
callbacks: {
onScroll: function() {},
onOverflowY: function() {
$("#chat").mCustomScrollbar("scrollTo","bottom", {scrollInertia: 0})
}
},
scrollInertia: 500,
advanced: {
updateOnContentResize: true
}
});
/* Special keypress events */
$("#map").keypress(function(event) {
if(event.which >= 49 && event.which <= 56) {
var slot = event.which - 49;
execute_spell(slot);
}
});
construct_menus();
//setTimeout(function() {
// $("#skin").append("<div class='popup_pane' id='statmenu'></div>");
//}, 1000);
// Send a message to the server that the client's UI is ready
byond.fn.topic("action=ui_ready");
}
/* Continously loop checking if jquery is initialized */
(function check_jquery() {
setTimeout(function() {
if(window.jQuery) {
init_ui();
} else {
check_jquery();
}
}, 500)
})();
},
/*
Receive messages from the server
*/
winset: function(props, sub) {
switch(props.cmd) {
// Update the player's HP meter
case "update-hp":
var coefficient = props.hp / props.max_hp;
var desired_width = 162 * coefficient;
$("#hpbar").animate({width: desired_width}, {queue: false, duration: 500});
byond.skin.output("hpnum", {text: coefficient * 100 + " % "});
break;
// Update a player's spell slot
case "update-spell":
var slot = "div#spell" + props.slot;
$(slot).css("background", "url(" + props.image + ")");
$(slot).css("cursor", "pointer");
hotbar[ parseInt(props.slot)-1 ] = props.ref;
break;
// Clear a player's spell slot
case "clear-spell":
var slot = "div#spell" + props.slot;
$(slot).css("background", "");
$(slot).css("cursor", "default");
hotbar[ parseInt(props.slot)-1 ] = "";
break;
// Enable or disable visual cooldown for a spell
case "cool-spell":
var slot = "div#spell" + props.slot;
if(props.status == "true") {
$(slot).fadeTo("fast", 0.3);
} else {
$(slot).fadeTo("fast", 1);
}
break;
/* menus and windows */
case "update-stat-pic":
$(".char-preview").css("background", "url(" + props.image + ")");
break;
case "toggle-menus":
$("#" + current_menu).toggle();
break;
}
}
}
};
})()
</script>
</byondclass>
<byondclass name="hpnum">
<script>
{
fn: {
output: function(obj,sub) {
this.elem.innerHTML = obj.null ? '' : obj.text;
}
}
}
</script>
</byondclass>
<byondclass name="mpnum">
<script>
{
fn: {
output: function(obj,sub) {
this.elem.innerHTML = obj.null ? '' : obj.text;
}
}
}
</script>
</byondclass>
<byondclass name="chat">
<script>
{
fn: {
winset: function(props, sub) {
if(window.jQuery) {
$("#chat .mCSB_container").append(props.text + "<br>");
var positionPercentage = $("#chat")[0].mcs.topPct;
if(positionPercentage>=90) {
$("#chat").mCustomScrollbar("scrollTo","bottom", {scrollInertia: 0});
}
}
}
}
}
</script>
</byondclass>
<style>
#cover {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: #000;
z-index: 10;
}
#map {
float: left;
display: inline-block;
width: 100%;
}
#chat {
font-smooth: never;
font-family: Consolas;
font-size: 13pt;
background: #816063;
position: fixed;
right: 0px;
top: 0px;
height: 150px;
width: 400px;
color: #FFF;
box-shadow: 0 0 5px #000;
border-left: #000 1px solid;
border-bottom: #000 1px solid;
text-shadow: 2px 2px #404040;
overflow-y: auto;
}
#hotbar {
position: fixed;
bottom: 0;
width: 330px;
height: 70px;
left: calc(50% - 165px);
}
#hotbar_nums {
position: fixed;
bottom: 0;
width: 330px;
height: 70px;
left: calc(50% - 165px);
z-index: 2;
pointer-events:none;
}
.spell {
position: relative;
width: 32px;
height: 32px;
top: 22px;
float: left;
transition:box-shadow .3s linear;
}
.spell:hover {
box-shadow: 0px 0px 15px #000;
}
#status {
position: fixed;
top: 5px;
left: 5px;
width: 238px;
height: 98px;
}
#hpbar {
position: fixed;
top: 19px;
left: 63px;
width: 162px;
height: 14px;
}
#mpbar {
position: fixed;
top: 49px;
left: 73px;
width: 160px;
height: 14px;
}
#hpnum, #mpnum {
text-align: center;
font-family: 'minimicraregular';
font-size: 14pt;
font-weight: bold;
color: #FFF;
text-shadow: 1px 0px 0px #000, 0px -1px 0px #000, 0px 1px 0px #000, -1px 0px 0px #000;
position: fixed;
}
#hpnum {
top: 16px;
left: 63px;
width: 162px;
}
#mpnum {
top: 46px;
left: 73px;
width: 160px;
}
/*
Menu stuff
*/
.popup_menu {
position: absolute;
color: #fff;
/*text-shadow: 1px 0px 0px #000, 0px -1px 0px #000, 0px 1px 0px #000, -1px 0px 0px #000;*/
text-shadow: 2px 0px 0px #000, 0px -2px 0px #000, 0px 2px 0px #000, -2px 0px 0px #000, -2px -2px 0px #000, 2px 2px 0px #000, 2px -2px 0px #000, -2px 2px 0px #000;
font-family: 'minimicraregular';
font-size: 17pt;
font-weight: bold;
}
.num {
color: #FFFD84;
display: inline;
}
#statmenu {
user-select: none;
width: 640px;
height: 434px;
top: calc(50% - 434px/2);
left: calc(50% - 640px/2);
background: url("stats_menu.png");
}
#statmenu > .left_pane {
height: 100%;
width: 186px;
text-align: center;
float: left;
padding-top: 5px;
}
#statmenu > .right_pane {
left: 15px;
position: relative;
padding-top: 5px;
height: 100%;
width: 431px;
text-align: center;
display: inline-block;
}
.stat-title {
margin-bottom: 24px;
font-size: 20pt;
}
.stat-mp {
margin-top: 2px;
margin-bottom: 19px;
}
.stat-melee { margin-bottom: 2px; }
.stat-magic { margin-bottom: 5px; }
.stat-agi { margin-bottom: 25px; }
.char-preview {
height: 64px;
width: 62px;
margin-top: 28px;
margin-left: auto;
margin-right: auto;
}
/*
Font stuff
*/
@font-face {
font-family: 'minimicraregular';
src: url('https://dl.dropboxusercontent.com/u/10657252/HTML5/minimicra.woff') format('woff');
font-weight: normal;
font-style: normal;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment