Skip to content

Instantly share code, notes, and snippets.

@onfi
Last active February 1, 2016 09:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save onfi/cdc00038dcdf6a157b5a to your computer and use it in GitHub Desktop.
Save onfi/cdc00038dcdf6a157b5a to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Resistance quest tool</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- load MUI -->
<link href="https://cdn.muicss.com/mui-0.1.17/css/mui.min.css" rel="stylesheet" type="text/css" />
<script src="https://cdn.muicss.com/mui-0.1.17/js/mui.min.js"></script>
<script src="https://cdn.jsdelivr.net/g/riot@2.2.1(riot.min.js+compiler.min.js)"></script>
<style type="text/css">
html, body, #main {height:100%;}
.mui-btn-dekai {
width: 100%;
height:3.5em;
font-size:3em;
}
</style>
<style>
div.timer {
position: absolute;
top:0;
right:0;
bottom:0;
left:0;
background-color: #E6855E;
}
div.timer > span {
position: fixed;
font-size: 100pt;
top: 50%;
left: 50%;
color: #F2F5AA;
transform:translate(-50%, -50%);
z-index: 100;
}
div.timer > div {
background-color: #F6CA06;
position: absolute;
top:0;
right:0;
bottom:0;
left:0;
z-index: 10;
}
@keyframes anime-background {
0% {
top: 0;
}
100% {
top: 100%;
}
}
</style>
</head>
<body>
<div class="mui-container" style="height:100%; padding:10%">
<div class="mui-row" id="main">
</div>
</div>
<script type="riot/tag">
<main>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<button class="mui-btn mui-btn-dekai mui-btn-danger mui-btn-raised" onclick={opts.controller.vote}>START</button>
</div>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<div class="mui-form-group">
<input type="text" class="mui-form-control" value={opts.quest.obe} onkeyup={ oberon }>
<label class="mui-form-floating-label">OBERON STRIKES BACK</label>
</div>
</div>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<button class="mui-btn mui-btn-primary mui-btn-raised" onclick={timer1}>1 min.</button>
<button class="mui-btn mui-btn-primary mui-btn-raised" onclick={timer3}>3 min.</button>
<button class="mui-btn mui-btn-primary mui-btn-raised" onclick={timer5}>5 min.</button>
</div>
<div class="col mui-col-md-8 mui-col-md-offset-2" style="margin-top: 10%">
<a href="https://www.youtube.com/watch?v=8SzpYqxjW10" target="r-a-nare">ナレーション オプションなし</a>
</div>
<div class="col mui-col-md-8 mui-col-md-offset-2" style="margin-top: 2%">
<a href="https://www.youtube.com/watch?v=jeyCFC_G95Q" target="r-a-nare">ナレーション フル</a>
</div>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<button class="mui-btn mui-btn-primary mui-btn-raised" onclick={opts.controller.inputMember}>メンバー決め</button>
</div>
timer1(e){
opts.controller.timer(1)
}
timer3(e){
opts.controller.timer(3)
}
timer5(e){
opts.controller.timer(5)
}
oberon(e){
opts.quest.oberon(e.target.value)
}
</main>
<vote>
<vote-success if={ this.random } />
<vote-failue if={ !this.random } />
<div class="col mui-col-sm-8 mui-col-sm-offset-2 mui-hidden-md mui-hidden-lg">&nbsp;</div>
<vote-failue if={ this.random } />
<vote-success if={ !this.random } />
this.random = (Math.floor( Math.random() * 2 ) == 1);
this.on('mount', function() {
this.clicked = false;
});
success(e) {
vote('success');
}
failure(e) {
vote('failure');
}
function vote(result){
if(!opts.controller.clicked) {
opts.controller.clicked = true;
opts.quest.vote(result);
opts.controller.voteResult();
}
}
</vote>
<vote-success>
<div class="col mui-col-sm-8 mui-col-sm-offset-2 mui-col-md-5 mui-col-md-offset-1">
<button class="mui-btn mui-btn-dekai mui-btn-primary mui-btn-raised" onclick={parent.success}>SUCCESS</button>
</div>
</vote-success>
<vote-failue>
<div class="col mui-col-sm-8 mui-col-sm-offset-2 mui-col-md-5 mui-col-md-offset-1">
<button class="mui-btn mui-btn-dekai mui-btn-danger mui-btn-raised" onclick={parent.failure}>FAILURE</button>
</div>
</vote-failue>
<voteResult>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<div class="mui-panel">
<h1>{unitName()}: {opts.quest.count()}</h1>
</div>
</div>
<div class="col mui-col-sm-8 mui-col-sm-offset-2 mui-col-md-5 mui-col-md-offset-1">
<button class="mui-btn mui-btn-dekai mui-btn-default mui-btn-raised" onclick={opts.controller.vote}>CONTINUE</button>
</div>
<div class="col mui-col-sm-8 mui-col-sm-offset-2 mui-hidden-md mui-hidden-lg">&nbsp;</div>
<div class="col mui-col-sm-8 mui-col-sm-offset-2 mui-col-md-5 mui-col-md-offset-1">
<button class="mui-btn mui-btn-accent mui-btn-raised" onclick={open}>OPEN</button>
</div>
unitName(){
if(opts.quest.count() == 1) {
return 'RESULT';
} else {
return 'RESULTS'
}
}
open() {
if(confirm("Do you want to open?")) {
opts.controller.result();
}
}
</voteResult>
<result>
<div class="col mui-col-md-8 mui-col-md-offset-2" if={!opts.quest.obe}>
<div class="mui-panel">
<h1>SUCCESS: {opts.quest.result['success']}</h1>
<h1>FAILURE: {opts.quest.result['failure']}</h1>
</div>
</div>
<div class="col mui-col-md-8 mui-col-md-offset-2" if={opts.quest.obe}>
<h1 if={!opts.quest.result['failure'] || opts.quest.result['failure'] < opts.quest.obe}>SUCCESS</h1>
<h1 if={opts.quest.result['failure'] >= opts.quest.obe}>FAILURE</h1>
</div>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<button class="mui-btn mui-btn-dekai mui-btn-danger mui-btn-raised" onclick={ init }>GO TO TOP</button>
</div>
this.delay = false
this.controller = opts.controller
setTimeout(function(){
this.delay = true
}, 3000)
init() {
if(this.delay) this.controller.init()
this.delay = true
}
</result>
<inputMember>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<div class="mui-form-group" each={ items }>
<input type="text" class="mui-form-control" value={members.names[index]} onkeyup={ parent.edit }>
<label class="mui-form-floating-label">参加者名</label>
</div>
</div>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<button class="mui-btn mui-btn-dekai mui-btn-danger mui-btn-raised" disabled={ count < 5 } onclick={ decision }>NEXT</button>
</div>
this.items = [];
this.members = opts.members;
this.count = this.members.names.length;
for(var i = 0; i < 10; i++){
this.items[this.items.length] = {index : i};
}
edit(e) {
this.members.names[e.item.index] = e.target.value;
this.count = 0;
for(var i = 0; i < this.members.names.length; i++){
if(this.members.names[i]) {
this.count++;
}
}
}
decision(e) {
var names = [];
for(var i = 0; i < this.members.names.length; i++){
if(this.members.names[i]) {
names[names.length] = this.members.names[i];
}
}
this.members.names = names;
opts.controller.selectCharactor();
}
</inputMember>
<selectCharactor>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<div onmousedown={ percival }>
<button class="mui-btn mui-btn-primary mui-btn-raised" disabled={ members.specials[0]['Percival'] == 0 }>パーシヴァル</button>
</div>
</div>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<div onmousedown={ mordred }>
<button class="mui-btn mui-btn-danger mui-btn-raised" disabled={ members.specials[1]['Mordred'] == 0 }>モードレッド</button>
</div>
<div onmousedown={ morgana }>
<button class="mui-btn mui-btn-danger mui-btn-raised" disabled={ members.specials[1]['Morgana'] == 0 }>モルガナ</button>
</div>
<div onmousedown={ oberon }>
<button class="mui-btn mui-btn-danger mui-btn-raised" disabled={ members.specials[1]['Oberon'] == 0 }>オベロン</button>
</div>
</div>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<button class="mui-btn mui-btn-dekai mui-btn-danger mui-btn-raised" onclick={ decision }>NEXT</button>
</div>
this.members = opts.members;
decision(e) {
this.members.init();
opts.controller.member(0);
}
percival(e) {
if(this.members.specials[0]['Percival'] == 0) {
this.members.specials[0]['Percival'] = 1;
} else {
this.members.specials[0]['Percival'] = 0;
}
}
mordred(e) {
if(this.members.specials[1]['Mordred'] == 0) {
this.members.specials[1]['Mordred'] = 1;
} else {
this.members.specials[1]['Mordred'] = 0;
}
}
morgana(e) {
if(this.members.specials[1]['Morgana'] == 0) {
this.members.specials[1]['Morgana'] = 1;
} else {
this.members.specials[1]['Morgana'] = 0;
}
}
oberon(e) {
if(this.members.specials[1]['Oberon'] == 0) {
this.members.specials[1]['Oberon'] = 1;
} else {
this.members.specials[1]['Oberon'] = 0;
}
}
</selectCharactor>
<member>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<div class="mui-panel">
<h1>{members.names[members.index]}さん</h1>
</div>
</div>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<button class="mui-btn mui-btn-primary mui-btn-raised" onclick={ open }>開く</button>
</div>
this.members = opts.members;
this.members.index = opts.idx;
open(e) {
if(confirm("Do you want to open?")) {
opts.controller.memberOpen();
}
}
</member>
<memberOpen>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<div class="mui-panel">
<h1>{members.names[members.index]}さん</h1>
<pre>{members.description(members.index)}</pre>
</div>
</div>
<div class="col mui-col-md-8 mui-col-md-offset-2">
<button class="mui-btn mui-btn-primary mui-btn-raised" onclick={ next }>次へ</button>
</div>
this.members = opts.members;
next(e) {
if((this.members.index + 1) < this.members.names.length){
opts.controller.member(this.members.index + 1);
} else {
opts.controller.init(0);
}
}
</memberOpen>
<timer>
<div class="timer"><div style="animation: anime-background { opts.minutes * 60 }s linear;"></div><span style="font-size: { screen.width * 0.3 }px" onclick="{opts.controller.init}">{ opts.minutes }</span></div>
</timer>
</script>
<script>
//model
var Quest = function(){
var elements = ['success', 'failure'];
this.result = {};
Quest.prototype.init = function(){
for(var i = 0; i < elements.length; i++) {
this.result[elements[i]] = 0;
}
}
Quest.prototype.vote = function(result){
this.result[result]++;
}
Quest.prototype.count = function(){
var cnt = 0;
for(var i = 0; i < elements.length; i++) {
cnt += this.result[elements[i]];
}
return cnt;
}
Quest.prototype.oberon = function(threshold){
var intThreshold = parseInt(threshold)
if(intThreshold) {
this.obe = intThreshold
} else {
this.obe = null
}
}
}
var CHARACTER_MERLIN = 1;
var CHARACTER_PERCIVAL = 2;
var CHARACTER_LOYAL_SERVANTS_OF_ARTHUR = 3;
var CHARACTER_ASSASSIN = 4;
var CHARACTER_MORDRED = 5;
var CHARACTER_MORGANA = 6;
var CHARACTER_OBERON = 7;
var CHARACTER_MINION_OF_MORDRED = 8;
var Member = function(_name, _character){
this.name = _name;
this.character = _character;
this.character_code = (function(_character){
if(_character == 'Merlin') return CHARACTER_MERLIN;
if(_character == 'Percival') return CHARACTER_PERCIVAL;
if(_character == 'Loyal Servants of Arthur') return CHARACTER_LOYAL_SERVANTS_OF_ARTHUR;
if(_character == 'Assassin') return CHARACTER_ASSASSIN;
if(_character == 'Mordred') return CHARACTER_MORDRED;
if(_character == 'Morgana') return CHARACTER_MORGANA;
if(_character == 'Oberon') return CHARACTER_OBERON;
if(_character == 'Minion of Mordred') return CHARACTER_MINION_OF_MORDRED;
})(_character);
}
var Members = function(){
var self = this;
var ARTHUR = 0;
var MORDRED = 1;
var TEAM_COUNT = {
2 : [1, 1],
3 : [2, 1],
4 : [3, 1],
5 : [3, 2],
6 : [4, 2],
7 : [4, 3],
8 : [5, 3],
9 : [6, 3],
10 : [7, 4],
}
self.specials = {}
self.specials[ARTHUR] =
{
'Merlin' : 2,
'Percival' : 1
};
self.specials[MORDRED] =
{
'Assassin' : 2,
'Mordred' : 1,
'Morgana' : 0,
'Oberon' : 0
};
self.index = 0;
self.names = [];
Members.prototype.add = function(){
if(self.count < 10) self.count++;
}
Members.prototype.remove = function(){
if(self.count > 5) self.count--;
}
Members.prototype.init = function(){
self.index = 0
var count = self.names.length;
var arthurCount = TEAM_COUNT[count][ARTHUR];
var mordredCount = TEAM_COUNT[count][MORDRED];
self.characters = [];
var arthurs = ['Merlin'];
if(self.specials[ARTHUR]['Percival']) arthurs[arthurs.length] = 'Percival';
for(var i = arthurs.length; i < arthurCount; i++) {
arthurs[arthurs.length] = 'Loyal Servants of Arthur';
}
var mordreds = ['Assassin'];
var fncs =
[
function(){if(self.specials[MORDRED]['Mordred'] && mordreds.length < mordredCount) mordreds[mordreds.length] = 'Mordred'},
function(){if(self.specials[MORDRED]['Morgana'] && mordreds.length < mordredCount) mordreds[mordreds.length] = 'Morgana'},
function(){if(self.specials[MORDRED]['Oberon'] && mordreds.length < mordredCount) mordreds[mordreds.length] = 'Oberon'}
];
self.randomSort(fncs);
for(var i = 0; i < fncs.length; i++) {
fncs[i]();
}
for(var i = mordreds.length; i < mordredCount; i++) {
mordreds[mordreds.length] = 'Minion of Mordred';
}
var characters = arthurs.concat(mordreds);
self.randomSort(characters);
self.members = [1,2,3];
for(var i = 0; i < self.names.length; i++) {
self.members[i] = new Member(self.names[i], characters[i]);
}
self.setCookie();
return self.members;
}
Members.prototype.description = function(index){
var member = self.members[index];
var mordredFoundEvel = self.mordredFindEvel();
var mordredFoundEvelText = "モードレッド陣営:";
for(var i = 0; i < mordredFoundEvel.length; i++) {
mordredFoundEvelText = mordredFoundEvelText + "\n " + mordredFoundEvel[i].name + "さん";
}
if(member.character_code == CHARACTER_MERLIN){
var merlinFoundEvel = self.merlinFindEvel();
var merlinFoundEvelText = "モードレッド陣営:";
for(var i = 0; i < merlinFoundEvel.length; i++) {
merlinFoundEvelText = merlinFoundEvelText + "\n " + merlinFoundEvel[i].name + "さん";
}
var text = "あなたはマーリンです。\n" + merlinFoundEvelText;
return text;
}
if(member.character_code == CHARACTER_PERCIVAL){
var foundMerlin = self.findMerlin();
var foundMerlinText = "マーリン:";
for(var i = 0; i < foundMerlin.length; i++) {
foundMerlinText = foundMerlinText + "\n " + foundMerlin[i].name + "さん";
}
var text = "あなたはパーシヴァルです。\n" + foundMerlinText;
return text;
}
if(member.character_code == CHARACTER_LOYAL_SERVANTS_OF_ARTHUR){
var text = "あなたはアーサーの忠実なる家来です。";
return text;
}
if(member.character_code == CHARACTER_ASSASSIN){
var text = "あなたは暗殺者です。\n" + mordredFoundEvelText;
return text;
}
if(member.character_code == CHARACTER_MORDRED){
var text = "あなたはモードレッドです。\n" + mordredFoundEvelText;
return text;
}
if(member.character_code == CHARACTER_MORGANA){
var text = "あなたはモルガナです。\n" + mordredFoundEvelText;
return text;
}
if(member.character_code == CHARACTER_OBERON){
var text = "あなたはオベロンです。";
return text;
}
if(member.character_code == CHARACTER_MINION_OF_MORDRED){
var text = "あなたはモードレッドのしもべです。\n" + mordredFoundEvelText;
return text;
}
}
Members.prototype.findMembers = function(_charcter_codes){
var result = [];
for(var i = 0; i < self.members.length; i++) {
for(var j = 0; j < _charcter_codes.length; j++) {
if(self.members[i].character_code == _charcter_codes[j]) {
result[result.length] = self.members[i];
break;
}
}
}
return result;
}
// モードレッド陣営で見える仲間(オベロンが見えない)
Members.prototype.mordredFindEvel = function(){
return self.findMembers([CHARACTER_ASSASSIN, CHARACTER_MORDRED, CHARACTER_MORGANA, CHARACTER_MINION_OF_MORDRED]);
}
// マーリンから見えるモードレッド陣営(モードレッドが見えない)
Members.prototype.merlinFindEvel = function(){
return self.findMembers([CHARACTER_ASSASSIN, CHARACTER_MORGANA, CHARACTER_OBERON, CHARACTER_MINION_OF_MORDRED]);
}
// マーリンを探す
Members.prototype.findMerlin = function(){
return self.findMembers([CHARACTER_MERLIN, CHARACTER_MORGANA]);
}
Members.prototype.random = function(cnt){
return Math.floor( Math.random() * cnt );
}
Members.prototype.randomSort = function(ary){
var algo =
function() {
return Math.random() - 0.5;
};
return ary.sort(algo).sort(algo).sort(algo).sort(algo);
}
Members.prototype.serialize = function(){
var obj = {};
obj['names'] = self.names;
obj['specials'] = self.specials;
return JSON.stringify(obj);
}
Members.prototype.deserialize = function(serial){
if(!serial) return;
if(serial == undefined) return;
if(serial == '') return;
if(typeof serial != "string") return;
if(!serial.startsWith('members=')) return;
var obj = JSON.parse(serial.replace('members=', ''));
if(!obj['names']) return;
if(!obj['specials']) return;
self.names = obj.names;
self.specials = obj.specials;
}
Members.prototype.setCookie = function() {
document.cookie = 'members=' + self.serialize() + '; expires=Tue, 31-Dec-2030 23:59:59';
}
Members.prototype.readCookie = function() {
self.deserialize(document.cookie);
}
self.readCookie();
}
var quest = new Quest();
var members = new Members();
// controller
var controller = {
init: function(wait){
quest.init();
controller.forward('main', {quest: quest}, wait);
},
vote: function(){
controller.clicked = false;
controller.forward('vote', {quest: quest});
},
voteResult: function(){
controller.forward('voteResult', {quest: quest});
},
result: function(){
controller.forward('result', {quest: quest});
},
inputMember: function(){
controller.forward('inputMember', {members: members});
},
selectCharactor: function(){
controller.forward('selectCharactor', {members: members});
},
member: function(idx){
controller.forward('member', {members: members, idx: idx}, 0);
},
memberOpen: function(){
controller.forward('memberOpen', {members: members});
},
timer: function(minutes){
controller.forward('timer', {minutes: minutes});
},
forward: function(tag, opts, wait) {
if(!opts) opts = {};
opts.controller = controller;
// 少しアニメを見せる
if(wait === undefined) wait = 200;
setTimeout(function(){
riot.mount('#main', tag, opts);
}, wait);
}
};
controller.init(0);
window.onbeforeunload = function(event){
event = event || window.event;
return event.returnValue = "Are you sure you want to exit this page?";
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment