2016-10-23 07:28:51 +02:00
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
function Dialog (game) {
|
|
|
|
|
this.game = game;
|
|
|
|
|
|
|
|
|
|
this.searcher = new Searcher();
|
|
|
|
|
|
|
|
|
|
this.warpDiv = this.newElement('div');
|
|
|
|
|
this.dialogDiv = this.newElement('div');
|
|
|
|
|
this.titleDiv = this.newElement('div');
|
|
|
|
|
this.closeIcon = this.newElement('div');
|
|
|
|
|
this.bodyDiv = this.newElement('div');
|
|
|
|
|
this.footerDiv = this.newElement('div');
|
|
|
|
|
this.footSpan = this.newElement('span');
|
|
|
|
|
this.okBtn = this.newElement('button');
|
|
|
|
|
this.cancelBtn = this.newElement('button');
|
|
|
|
|
|
|
|
|
|
this.okBtn.textContent = Localize('common','OK');
|
|
|
|
|
this.cancelBtn.textContent = Localize('common','CANCEL');
|
|
|
|
|
this.closeIcon.onclick = this.close.bind(this);
|
|
|
|
|
|
|
|
|
|
this.warpDiv.classList.add('warp');
|
|
|
|
|
this.dialogDiv.classList.add('dialog');
|
|
|
|
|
this.titleDiv.classList.add('title');
|
|
|
|
|
this.closeIcon.classList.add('closeIcon');
|
|
|
|
|
this.bodyDiv.classList.add('body');
|
|
|
|
|
this.footerDiv.classList.add('footer');
|
|
|
|
|
this.okBtn.classList.add('okBtn');
|
|
|
|
|
this.cancelBtn.classList.add('cancelBtn');
|
|
|
|
|
|
|
|
|
|
this.warpDiv.appendChild(this.dialogDiv);
|
|
|
|
|
this.dialogDiv.appendChild(this.closeIcon);
|
|
|
|
|
this.dialogDiv.appendChild(this.titleDiv);
|
|
|
|
|
this.dialogDiv.appendChild(this.bodyDiv);
|
|
|
|
|
this.dialogDiv.appendChild(this.footerDiv);
|
|
|
|
|
this.footerDiv.appendChild(this.footSpan);
|
|
|
|
|
this.footerDiv.appendChild(this.okBtn);
|
|
|
|
|
this.footerDiv.appendChild(this.cancelBtn);
|
|
|
|
|
|
|
|
|
|
this.warpDiv.style.display = 'none';
|
|
|
|
|
game.stage.canvas.parentElement.appendChild(this.warpDiv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Dialog.prototype.newElement = function (tag) {
|
|
|
|
|
return document.createElement(tag);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Dialog.prototype.newCardImg = function (pid) {
|
|
|
|
|
var img = this.newElement('img');
|
|
|
|
|
img.src = this.game.imageManager.getUrlByPid(pid);
|
|
|
|
|
return img;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Dialog.prototype.mouseover = function (el,pid) {
|
|
|
|
|
el.onmouseover = this.game.cardDetail.show.bind(this.game.cardDetail,pid);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Dialog.prototype.center = function (element) {
|
|
|
|
|
var parent = element.parentElement;
|
|
|
|
|
element.style.top = '0';
|
|
|
|
|
element.style.left = '0';
|
|
|
|
|
element.style.top = (parent.offsetHeight - element.offsetHeight)/2 + 'px';
|
|
|
|
|
element.style.left = (parent.offsetWidth - element.offsetWidth)/2 + 'px';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Dialog.prototype.pop = function (title,body,foot,canClose,callback,callbackCancel) {
|
|
|
|
|
var dialog = this;
|
|
|
|
|
// 构筑DOM
|
|
|
|
|
this.titleDiv.textContent = title;
|
|
|
|
|
this.footSpan.innerHTML = '';
|
|
|
|
|
if (foot) this.footSpan.appendChild(foot);
|
|
|
|
|
this.bodyDiv.innerHTML = '';
|
|
|
|
|
this.bodyDiv.style.width = '';
|
|
|
|
|
this.bodyDiv.appendChild(body);
|
|
|
|
|
this.closeIcon.style.display = canClose? '' : 'none';
|
|
|
|
|
if (!callback) {
|
|
|
|
|
this.okBtn.onclick = null;
|
|
|
|
|
this.footerDiv.style.display = 'none';
|
|
|
|
|
} else {
|
|
|
|
|
this.okBtn.onclick = function (event) {
|
|
|
|
|
dialog.close();
|
|
|
|
|
callback();
|
|
|
|
|
};
|
|
|
|
|
// this.okBtn.disabled = false;
|
|
|
|
|
this.footerDiv.style.display = '';
|
|
|
|
|
}
|
|
|
|
|
if (!callbackCancel) {
|
|
|
|
|
this.cancelBtn.onclick = null;
|
|
|
|
|
this.cancelBtn.style.display = 'none';
|
|
|
|
|
} else {
|
|
|
|
|
this.cancelBtn.onclick = function (event) {
|
|
|
|
|
dialog.close();
|
|
|
|
|
callbackCancel();
|
|
|
|
|
};
|
|
|
|
|
// this.cancelBtn.disabled = false;
|
|
|
|
|
this.cancelBtn.style.display = '';
|
|
|
|
|
}
|
|
|
|
|
// 渲染,但完全透明,用于计算元素尺寸和位置.
|
|
|
|
|
this.warpDiv.style.opacity = '0';
|
|
|
|
|
this.warpDiv.style.display = '';
|
|
|
|
|
// 加上滚动条宽度
|
|
|
|
|
// this.bodyDiv.style.width = 2*this.bodyDiv.offsetWidth - this.bodyDiv.clientWidth + 'px';
|
|
|
|
|
// 居中
|
|
|
|
|
this.center(this.dialogDiv);
|
|
|
|
|
// 显示
|
|
|
|
|
this.warpDiv.style.opacity = '1';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Dialog.prototype.close = function () {
|
|
|
|
|
this.okBtn.disabled = false;
|
|
|
|
|
this.warpDiv.style.display = 'none';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Dialog.prototype.showText = function (title,text,callback) {
|
|
|
|
|
var body = document.createTextNode(text);
|
|
|
|
|
this.pop(title,body,null,false,callback);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Dialog.prototype.confirm = function (title,text,callback) {
|
|
|
|
|
var body = document.createTextNode(text);
|
|
|
|
|
this.pop(title,body,null,false,callback.bind(null,true),callback.bind(null,false));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 从多个文本选项选择一个.
|
|
|
|
|
Dialog.prototype.selectText = function (title,options,canClose,callback) {
|
|
|
|
|
var dialog = this;
|
|
|
|
|
var body = this.newElement('div');
|
|
|
|
|
options.forEach(function (option,idx) {
|
|
|
|
|
var opt = this.newElement('div');
|
|
|
|
|
opt.classList.add('option');
|
|
|
|
|
opt.textContent = option;
|
|
|
|
|
body.appendChild(opt);
|
|
|
|
|
|
|
|
|
|
opt.onclick = function (event) {
|
|
|
|
|
dialog.close();
|
|
|
|
|
callback(idx);
|
|
|
|
|
}
|
|
|
|
|
},this);
|
|
|
|
|
this.pop(title,body,null,canClose,null);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Dialog.prototype.selectNumber = function (title,min,max,defaultValue,canClose,callback) {
|
|
|
|
|
var dialog = this;
|
|
|
|
|
var body = this.newElement('div');
|
|
|
|
|
var sel = this.newElement('select');
|
|
|
|
|
for (var i = min; i <= max; i++) {
|
|
|
|
|
var opt = this.newElement('option');
|
|
|
|
|
opt.value = i;
|
|
|
|
|
opt.textContent = i;
|
|
|
|
|
sel.appendChild(opt);
|
|
|
|
|
}
|
|
|
|
|
sel.value = defaultValue;
|
|
|
|
|
body.appendChild(sel);
|
|
|
|
|
this.pop(title,body,null,canClose,function () {
|
|
|
|
|
callback(sel.value);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Dialog.prototype.showCards = function (title,cards,callback) {
|
|
|
|
|
var body = this.newElement('div');
|
|
|
|
|
if (!cards.length) {
|
|
|
|
|
body.textContent = Localize('common','NO_CARDS');
|
|
|
|
|
} else {
|
|
|
|
|
cards.forEach(function (card) {
|
|
|
|
|
var crd = this.newElement('div');
|
|
|
|
|
var img = this.newCardImg(card.pid);
|
|
|
|
|
|
|
|
|
|
crd.appendChild(img);
|
|
|
|
|
crd.classList.add('card');
|
|
|
|
|
this.mouseover(crd,card.pid);
|
|
|
|
|
|
|
|
|
|
body.appendChild(crd);
|
|
|
|
|
},this);
|
|
|
|
|
}
|
|
|
|
|
this.pop(title,body,null,false,callback);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Dialog.prototype.selectCardId = function (title,callback) {
|
|
|
|
|
var dialog = this;
|
|
|
|
|
var searcher = this.searcher;
|
|
|
|
|
|
|
|
|
|
var body = this.newElement('div');
|
|
|
|
|
body.style.textAlign = 'center';
|
|
|
|
|
|
|
|
|
|
var searchBar = this.newElement('input');
|
|
|
|
|
searchBar.setAttribute('placeholder','Search...');
|
|
|
|
|
searchBar.type = 'text';
|
|
|
|
|
searchBar.style.textAlign = 'center';
|
|
|
|
|
searchBar.style.width = '90%';
|
|
|
|
|
|
|
|
|
|
var container = this.newElement('div');
|
|
|
|
|
container.style.maxHeight = '450px';
|
|
|
|
|
container.style['overflow-y'] = 'auto';
|
|
|
|
|
container.style.textAlign = 'left';
|
|
|
|
|
|
|
|
|
|
var elShowMore = this.newElement('div');
|
|
|
|
|
elShowMore.textContent = 'Show More...';
|
|
|
|
|
elShowMore.style.color = 'blue';
|
|
|
|
|
elShowMore.style.cursor = 'pointer';
|
|
|
|
|
elShowMore.style.margin = '1em 0';
|
|
|
|
|
|
|
|
|
|
body.appendChild(searchBar);
|
|
|
|
|
body.appendChild(container);
|
|
|
|
|
body.appendChild(elShowMore);
|
|
|
|
|
|
|
|
|
|
var results = [];
|
|
|
|
|
var RESULTS_LENGTH = 9;
|
|
|
|
|
var _shown = 0;
|
|
|
|
|
elShowMore.onclick = showMore;
|
|
|
|
|
searchBar.onchange = searchBar.onkeyup = search;
|
|
|
|
|
function search () {
|
|
|
|
|
var q = searchBar.value;
|
|
|
|
|
results = searcher.search(q);
|
|
|
|
|
showResults();
|
|
|
|
|
};
|
|
|
|
|
search();
|
|
|
|
|
function showResults () {
|
|
|
|
|
_shown = 0;
|
|
|
|
|
container.innerHTML = '';
|
|
|
|
|
showMore();
|
|
|
|
|
}
|
|
|
|
|
function showMore () {
|
|
|
|
|
for (var i = 0; i < RESULTS_LENGTH; i++) {
|
|
|
|
|
var idx = _shown;
|
|
|
|
|
if (idx >= results.length) break;
|
|
|
|
|
var pid = results[idx].pid;
|
|
|
|
|
|
|
|
|
|
var opt = dialog.newElement('div');
|
|
|
|
|
var img = dialog.newCardImg(pid);
|
|
|
|
|
|
|
|
|
|
opt.appendChild(img);
|
|
|
|
|
opt.classList.add('card');
|
|
|
|
|
dialog.mouseover(opt,pid);
|
|
|
|
|
|
|
|
|
|
opt.onclick = function (pid) {
|
|
|
|
|
dialog.close();
|
|
|
|
|
callback(pid);
|
|
|
|
|
}.bind(null,pid);
|
|
|
|
|
|
|
|
|
|
container.appendChild(opt);
|
|
|
|
|
_shown++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if (_shown < results.length) {
|
|
|
|
|
// show(elShowMore);
|
|
|
|
|
// } else {
|
|
|
|
|
// hide(elShowMore);
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
this.pop(title,body,null,false,null);
|
|
|
|
|
|
|
|
|
|
// 固定宽度
|
|
|
|
|
body.style.minWidth = body.offsetWidth + 'px';
|
|
|
|
|
searchBar.focus();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 选择一张.
|
|
|
|
|
Dialog.prototype.selectCard = function (title,cards,canClose,callback) {
|
|
|
|
|
var dialog = this;
|
|
|
|
|
var body = this.newElement('div');
|
|
|
|
|
cards.forEach(function (card,idx) {
|
|
|
|
|
var opt = this.newElement('div');
|
|
|
|
|
var img = this.newCardImg(card.pid);
|
|
|
|
|
|
|
|
|
|
opt.appendChild(img);
|
|
|
|
|
opt.classList.add('card');
|
|
|
|
|
this.mouseover(opt,card.pid);
|
|
|
|
|
|
|
|
|
|
opt.onclick = function (event) {
|
|
|
|
|
dialog.close();
|
|
|
|
|
callback(idx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
body.appendChild(opt);
|
|
|
|
|
},this);
|
|
|
|
|
this.pop(title,body,null,canClose,null);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Dialog.prototype.selectCardAdvanced = function (title,cards,texts,canClose,careOrder,onchanged,callback,callbackCancel) {
|
|
|
|
|
if (!texts) texts = [];
|
|
|
|
|
var dialog = this;
|
|
|
|
|
var selectedIndexes = [];
|
|
|
|
|
var datas = [];
|
|
|
|
|
var body = this.newElement('div');
|
|
|
|
|
cards.forEach(function (card,idx) {
|
|
|
|
|
var opt = this.newElement('div');
|
|
|
|
|
var img = this.newCardImg(card.pid);
|
|
|
|
|
var txt = this.newElement('div');
|
|
|
|
|
txt.textContent = texts[idx] || '';
|
|
|
|
|
var msk = this.newElement('div');
|
|
|
|
|
var num = this.newElement('div');
|
|
|
|
|
|
|
|
|
|
opt.appendChild(img);
|
|
|
|
|
opt.appendChild(txt);
|
|
|
|
|
opt.appendChild(msk);
|
|
|
|
|
opt.appendChild(num);
|
|
|
|
|
|
|
|
|
|
opt.classList.add('card');
|
|
|
|
|
txt.classList.add('txt');
|
|
|
|
|
msk.classList.add('msk');
|
|
|
|
|
num.classList.add('num');
|
|
|
|
|
this.mouseover(opt,card.pid);
|
|
|
|
|
|
|
|
|
|
var data = {
|
|
|
|
|
opt: opt,
|
|
|
|
|
txt: txt,
|
|
|
|
|
msk: msk,
|
|
|
|
|
num: num,
|
|
|
|
|
};
|
|
|
|
|
datas[idx] = data;
|
|
|
|
|
|
|
|
|
|
opt.onclick = function (event) {
|
|
|
|
|
if (!opt.classList.contains('selected') && opt.classList.contains('disabled')) return;
|
|
|
|
|
if (opt.classList.contains('selected')) {
|
|
|
|
|
removeFromArr(idx,selectedIndexes);
|
|
|
|
|
} else {
|
|
|
|
|
selectedIndexes.push(idx);
|
|
|
|
|
}
|
|
|
|
|
opt.classList.toggle('selected');
|
|
|
|
|
handleSelectChanged();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
body.appendChild(opt);
|
|
|
|
|
},this);
|
|
|
|
|
|
|
|
|
|
handleSelectChanged();
|
|
|
|
|
dialog.pop(title,body,null,canClose,callback.bind(null,selectedIndexes),callbackCancel);
|
|
|
|
|
datas.forEach(function (data) {
|
|
|
|
|
this.center(data.txt);
|
|
|
|
|
},this);
|
|
|
|
|
|
|
|
|
|
function handleSelectChanged () {
|
|
|
|
|
datas.forEach(function (data,idx) {
|
|
|
|
|
data.opt.classList.remove('disabled');
|
|
|
|
|
},this);
|
|
|
|
|
var ok = onchanged(selectedIndexes,disable);
|
|
|
|
|
dialog.okBtn.disabled = !ok;
|
|
|
|
|
if (careOrder) {
|
|
|
|
|
datas.forEach(function (data,idx) {
|
|
|
|
|
var order = selectedIndexes.indexOf(idx) + 1;
|
|
|
|
|
data.num.textContent = order || '';
|
|
|
|
|
dialog.center(data.num);
|
|
|
|
|
},this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
function disable (idx) {
|
|
|
|
|
datas[idx].opt.classList.add('disabled');
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 选择若干张.
|
|
|
|
|
Dialog.prototype.selectSomeCards = function (title,cards,arg,callback) {
|
|
|
|
|
var min = arg.min || 0;
|
|
|
|
|
// var max = arg.max || cards.length;
|
|
|
|
|
var max = arg.max;
|
|
|
|
|
if (!max) {
|
|
|
|
|
max = arg.targets? arg.targets.length : cards.length;
|
|
|
|
|
}
|
|
|
|
|
var texts = arg.texts;
|
|
|
|
|
var canClose = arg.canClose;
|
|
|
|
|
var careOrder = arg.careOrder;
|
|
|
|
|
var targets = arg.targets;
|
|
|
|
|
var callbackCancel;
|
|
|
|
|
if (min) {
|
|
|
|
|
callbackCancel = null;
|
|
|
|
|
} else {
|
|
|
|
|
callbackCancel = callback.bind(null,[]);
|
|
|
|
|
}
|
|
|
|
|
this.selectCardAdvanced(title,cards,texts,canClose,careOrder,function (selectedIndexes,disable) {
|
|
|
|
|
if (targets && targets.length) {
|
|
|
|
|
cards.forEach(function (card,idx) {
|
|
|
|
|
if (!inArr(card,targets)) disable(idx);
|
|
|
|
|
},this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var len = selectedIndexes.length;
|
|
|
|
|
if (len >= max) {
|
|
|
|
|
cards.forEach(function (card,idx) {
|
|
|
|
|
disable(idx);
|
|
|
|
|
},this);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return len && (len >= min);
|
|
|
|
|
},function (selectedIndexes) {
|
|
|
|
|
if (targets && targets.length && (targets.length !== cards.length)) {
|
|
|
|
|
selectedIndexes = selectedIndexes.map(function (idx) {
|
|
|
|
|
return targets.indexOf(cards[idx]);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
callback(selectedIndexes);
|
|
|
|
|
},callbackCancel);
|
|
|
|
|
};
|
|
|
|
|
|
2017-08-05 17:15:32 +02:00
|
|
|
|
Dialog.prototype.selectEner = function (title,cards,integers,cost,callback,onCancel) {
|
|
|
|
|
function checkRequirements(items, requirements) {
|
|
|
|
|
var n = requirements.length
|
|
|
|
|
var len = 1 << n
|
|
|
|
|
var arr = (typeof Uint8Array === 'undefined') ? new Array(len) : new Uint8Array(len)
|
|
|
|
|
// 第 i 条不等式。
|
|
|
|
|
// 假设 n == 4,即有 4 种元需求:
|
|
|
|
|
// i 为从 0000 到 1111,从右到左分别称为第 1,2,3,4 位
|
|
|
|
|
// 当 i == 0110 时,代表不等式左边为第 2、3 个集合的并集
|
|
|
|
|
for (var i = 0; i < len; i++) {
|
|
|
|
|
var filters = []
|
|
|
|
|
for (var j = 0; j < n; j++) {
|
|
|
|
|
if (i & (1 << j)) {
|
|
|
|
|
filters.push(requirements[j].filter)
|
|
|
|
|
// 不等式的右边(先把需求数加上去,满足的时候减 1,减至 0 则满足该不等式)
|
|
|
|
|
arr[i] += requirements[j].count
|
|
|
|
|
}
|
2016-10-23 07:28:51 +02:00
|
|
|
|
}
|
2017-08-05 17:15:32 +02:00
|
|
|
|
// 遍历能量区,满足条件的减 1
|
|
|
|
|
for (var j = 0; j < items.length; j++) {
|
|
|
|
|
var item = items[j]
|
|
|
|
|
if (filters.some(function (filter) {
|
|
|
|
|
return filter(item)
|
|
|
|
|
})) {
|
|
|
|
|
// 减至 0,该不等式成立
|
|
|
|
|
if (!--arr[i]) break
|
2016-10-23 07:28:51 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-08-05 17:15:32 +02:00
|
|
|
|
if (arr[i]) return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
2016-10-23 07:28:51 +02:00
|
|
|
|
|
2017-08-05 17:15:32 +02:00
|
|
|
|
var total = 0;
|
|
|
|
|
var requirements = cost.requirements.map(function (requirement) {
|
|
|
|
|
total += requirement.count;
|
|
|
|
|
return {
|
|
|
|
|
count: requirement.count,
|
|
|
|
|
mask: requirement.mask,
|
|
|
|
|
filter: function (int) {
|
2017-08-23 16:17:04 +02:00
|
|
|
|
return !requirement.mask || (int & requirement.mask);
|
2017-08-05 17:15:32 +02:00
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
function onSelectChange (selectedIndexes,disable) {
|
|
|
|
|
var selectedIntegers = selectedIndexes.map(function (index) {
|
|
|
|
|
return integers[index]
|
|
|
|
|
});
|
|
|
|
|
var ok = (selectedIndexes.length === total) && checkRequirements(selectedIntegers,requirements);
|
|
|
|
|
if (ok) {
|
|
|
|
|
integers.forEach(function (_,index) {
|
|
|
|
|
disable(index);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
return ok;
|
|
|
|
|
};
|
2016-10-23 07:28:51 +02:00
|
|
|
|
|
2017-08-05 17:15:32 +02:00
|
|
|
|
var texts = cards.map(function (card) {
|
|
|
|
|
return card.sid === cost.source ? 'WARN' : '';
|
|
|
|
|
},this);
|
|
|
|
|
this.selectCardAdvanced(title,cards,texts,false,false,onSelectChange,callback,onCancel);
|
2016-10-23 07:28:51 +02:00
|
|
|
|
};
|