forked from devsam/core
빙의 장수 기능 추가(선택은 미완)
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
body {
|
||||
color:white; background-color:black; font-family: '맑은 고딕';
|
||||
}
|
||||
|
||||
table {
|
||||
border: solid 1px; border-spacing: 0px; border-collapse: separate; border-top-color: gray; border-left-color: gray; border-right-color: black; border-bottom-color: black;
|
||||
padding: 0px;
|
||||
@@ -25,6 +26,7 @@ a.just_link {
|
||||
}
|
||||
|
||||
.with_border{
|
||||
margin:0;
|
||||
border: solid 1px;
|
||||
border-spacing: 0px;
|
||||
border-collapse: separate;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
.card_holder{
|
||||
text-align:center;
|
||||
}
|
||||
.general_card{
|
||||
width:100px;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
|
||||
.general_card label {
|
||||
display: block;
|
||||
padding-left: 15px;
|
||||
text-indent: -15px;
|
||||
}
|
||||
|
||||
.general_card input {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
padding: 0;
|
||||
margin:0;
|
||||
vertical-align: bottom;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
*overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
const VALID_MINUTE = 5;
|
||||
const PICK_MORE_MINUTE = 2;
|
||||
const KEEP_CNT = 3;
|
||||
|
||||
|
||||
$refresh = Util::getReq('refresh', 'bool', false);
|
||||
$keepResult = Util::getReq('keep', 'array_int', []);
|
||||
|
||||
$session = Session::requireLogin([])->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
|
||||
$oNow = new \DateTimeImmutable();
|
||||
|
||||
$now = $oNow->format('Y-m-d H:i:s');
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$oldGeneral = $db->queryFirstField('SELECT `no` FROM general WHERE `owner`=%i', $userID);
|
||||
if($oldGeneral !== null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'이미 장수가 생성되었습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
list(
|
||||
$year,
|
||||
$month,
|
||||
$maxgeneral,
|
||||
$turnterm,
|
||||
$genius,
|
||||
$npcmode
|
||||
) = $db->queryFirstList('SELECT year,month,maxgeneral,turnterm,genius,npcmode from game limit 1');
|
||||
|
||||
if(!$npcmode){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'빙의 가능한 서버가 아닙니다'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$token = $db->queryFirstRow('SELECT * FROM select_npc_token WHERE `owner`=%i AND `valid_until`>=%s', $userID, $now);
|
||||
$pickResult = [];
|
||||
|
||||
|
||||
if($token && $refresh){
|
||||
$pickMoreFrom = (new \DateTime($token['pick_more_from']))->getTimestamp();
|
||||
$nowT = $oNow->getTimestamp();
|
||||
|
||||
if($nowT >= $pickMoreFrom){
|
||||
$oldPickResult = Json::decode($token['pick_result']);
|
||||
|
||||
foreach($keepResult as $keepId){
|
||||
if(\key_exists($keepId, $oldPickResult) && $oldPickResult[$keepId]['keepCnt'] > 0){
|
||||
$pickResult[$keepId] = $oldPickResult[$keepId];
|
||||
$pickResult[$keepId]['keepCnt']-=1;
|
||||
}
|
||||
}
|
||||
|
||||
if(count($pickResult) == count($oldPickResult)){
|
||||
$refresh = false;
|
||||
}
|
||||
}
|
||||
else{
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'아직 다시 뽑을 수 없습니다',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if($token && !$refresh){
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'pick'=>Json::decode($token['pick_result']),
|
||||
'pickMoreFrom'=>$token['pick_more_from'],
|
||||
'validUntil'=>$token['valid_until']
|
||||
]);
|
||||
}
|
||||
|
||||
$candidates = [];
|
||||
|
||||
$weight = [];
|
||||
foreach($db->query('SELECT `no`, `name`, leader, power, intel, imgsvr, picture, special, special2 FROM general WHERE npc=2') as $general){
|
||||
$general['special'] = \sammo\SpecialityConst::DOMESTIC[$general['special']][0]??'-';
|
||||
$general['special2'] = \sammo\SpecialityConst::WAR[$general['special2']][0]??'-';
|
||||
$candidates[$general['no']] = $general + ['keepCnt'=>KEEP_CNT];
|
||||
$allStat = $general['leader'] + $general['power'] + $general['intel'];
|
||||
$weight[$general['no']] = pow($allStat, 1.7);
|
||||
}
|
||||
|
||||
foreach($db->queryFirstColumn('SELECT pick_result FROM select_npc_token WHERE `owner`!=%i AND valid_until >=%s', $userID, $now) as $reserved){
|
||||
$reserved = Json::decode($reserved);
|
||||
foreach(array_keys($reserved) as $reservedNPC){
|
||||
if(key_exists($reservedNPC, $weight)){
|
||||
unset($candidates[$reservedNPC]);
|
||||
unset($weight[$reservedNPC]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$pickLimit = min(count($candidates), 5);
|
||||
|
||||
while(count($pickResult) < $pickLimit){
|
||||
$generalID = Util::choiceRandomUsingWeight($weight);
|
||||
if(!key_exists($generalID, $pickResult)){
|
||||
$pickResult[$generalID] = $candidates[$generalID];
|
||||
}
|
||||
}
|
||||
|
||||
$newNonce = mt_rand(0, 0xfffffff);
|
||||
|
||||
$validMinute = max(VALID_MINUTE, intdiv($turnterm, 2));
|
||||
$pickMoreMinute = max(PICK_MORE_MINUTE, intdiv($turnterm, 5));
|
||||
|
||||
$validUntil = $oNow->add(new \DateInterval(sprintf('PT%dM', $validMinute)));
|
||||
$pickMoreFrom = $oNow->add(new \DateInterval(sprintf('PT%dM', $pickMoreMinute)));
|
||||
|
||||
$db->query('LOCK TABLES select_npc_token WRITE');
|
||||
|
||||
$db->delete('select_npc_token', 'valid_until < %s', $now);
|
||||
|
||||
$inserted = 0;
|
||||
|
||||
if($token){
|
||||
$db->update('select_npc_token', [
|
||||
'valid_until'=>$validUntil->format('Y-m-d H:i:s'),
|
||||
'pick_more_from'=>$pickMoreFrom->format('Y-m-d H:i:s'),
|
||||
'pick_result'=>Json::encode($pickResult),
|
||||
'nonce'=>$newNonce
|
||||
], 'owner = %i AND nonce = %i', $userID, $token['nonce']);
|
||||
if($db->affectedRows()){
|
||||
$inserted = -1;
|
||||
}
|
||||
}
|
||||
else{
|
||||
$db->insertIgnore('select_npc_token', [
|
||||
'owner'=>$userID,
|
||||
'valid_until'=>$validUntil->format('Y-m-d H:i:s'),
|
||||
'pick_more_from'=>'2000-01-01 01:00:00',
|
||||
'pick_result'=>Json::encode($pickResult),
|
||||
'nonce'=>$newNonce
|
||||
]);
|
||||
|
||||
if($db->affectedRows()){
|
||||
$inserted = 1;
|
||||
}
|
||||
}
|
||||
|
||||
$db->query('UNLOCK TABLES');
|
||||
|
||||
if($inserted === 0){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'중복 요청, 다시 랜덤 토큰을 확인해주세요'
|
||||
]);
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'pick'=>$pickResult,
|
||||
'pickMoreFrom'=>($inserted===-1)?$pickMoreFrom->format('Y-m-d H:i:s'):'2000-01-01 01:00:00',
|
||||
'validUntil'=>$validUntil->format('Y-m-d H:i:s')
|
||||
]);
|
||||
@@ -0,0 +1,76 @@
|
||||
var templateGeneralCard =
|
||||
'<div class="general_card">\
|
||||
<h4 class="bg1 with_border"><%name%></h4>\
|
||||
<h4><img src="<%iconPath%>" height=64 width=64></h4>\
|
||||
<p><%leader%> / <%power%> / <%intel%><br>\
|
||||
<%special%> / <%special2%></p>\
|
||||
<button type="subject" class="with_skin with_border select_btn" value="<%no%>" name="pick">빙의하기</button>\
|
||||
<label><input <%keepCnt?"":disabled="disabled"%> type="checkbox" value="<%no%>" name="keep[]" class="keep_select">보관(<%keepCnt%>회)</label>\
|
||||
</div>';
|
||||
|
||||
function updatePickMoreTimer(){
|
||||
var $btn = $('#btn_pick_more');
|
||||
var now = Date.now();
|
||||
var remain = ($btn.data('available') - now) / 1000;
|
||||
if(remain <= 0){
|
||||
$btn.prop('disabled', false)
|
||||
$btn.html('다른 장수 보기');
|
||||
return;
|
||||
}
|
||||
|
||||
$btn.html('다른 장수 보기({0}초)'.format(Math.ceil(remain)));
|
||||
|
||||
setTimeout(updatePickMoreTimer, 250);
|
||||
}
|
||||
|
||||
function printGenerals(value){
|
||||
$('.card_holder').empty();
|
||||
$('#valid_until_text').html(value.validUntil);
|
||||
$('#btn_pick_more').data('available', new Date(value.pickMoreFrom).getTime()).prop('disabled',true);
|
||||
$.each(value.pick, function(idx, cardData){
|
||||
cardData.iconPath = getIconPath(cardData.imgsvr, cardData.picture);
|
||||
console.log(cardData);
|
||||
|
||||
var $card = $(TemplateEngine(templateGeneralCard, cardData));
|
||||
console.log($card);
|
||||
|
||||
$('.card_holder').append($card);
|
||||
});
|
||||
|
||||
updatePickMoreTimer();
|
||||
}
|
||||
|
||||
jQuery(function($){
|
||||
|
||||
$.post('j_get_select_npc_token.php').then(function(value){
|
||||
if(!value.result){
|
||||
alert(value.reason);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(value);
|
||||
printGenerals(value);
|
||||
});
|
||||
|
||||
$('#btn_pick_more').click(function(){
|
||||
var generals = $.map($('.keep_select:checked'), function(value){
|
||||
return $(value).val();
|
||||
});
|
||||
console.log(generals);
|
||||
$.post({
|
||||
url:'j_get_select_npc_token.php',
|
||||
dataType:'json',
|
||||
data:{
|
||||
refresh:true,
|
||||
keep:generals
|
||||
}
|
||||
}).then(function(result){
|
||||
if(!result.result){
|
||||
alert(result.reason);
|
||||
location.refresh();
|
||||
}
|
||||
printGenerals(result);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
$session = Session::requireLogin()->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
$rootDB = RootDB::db();
|
||||
$db = DB::db();
|
||||
|
||||
//회원 테이블에서 정보확인
|
||||
$member = $rootDB->queryFirstRow('select no,name,picture,grade from member where no=%i', $userID);
|
||||
|
||||
if(!$member) {
|
||||
$session->logout();
|
||||
header('location:..');
|
||||
die();
|
||||
}
|
||||
|
||||
list($npcmode, $maxgeneral) = $db->queryFirstList('SELECT npcmode,maxgeneral FROM game LIMIT 1');
|
||||
|
||||
if(!$npcmode) {
|
||||
header('location:..');
|
||||
die();
|
||||
}
|
||||
|
||||
$gencount = $db->queryFirstField('SELECT count(`no`) FROM general WHERE npc<2');
|
||||
|
||||
$nations = $db->queryAllLists('SELECT `name`, scoutmsg, color FROM nation');
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><?=UniqueConst::$serverName?>: NPC빙의</title>
|
||||
<meta HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=utf-8'>
|
||||
<link rel='stylesheet' href='css/normalize.css' type='text/css'>
|
||||
<link rel='stylesheet' href='../d_shared/common.css' type='text/css'>
|
||||
<link rel='stylesheet' href='../css/config.css' type='text/css'>
|
||||
<link rel='stylesheet' href='css/common.css' type='text/css'>
|
||||
<link rel='stylesheet' href='css/select_npc.css' type='text/css'>
|
||||
<script type="text/javascript" src="../d_shared/common_path.js"></script>
|
||||
<script type="text/javascript" src="../js/common.js"></script>
|
||||
<script type="text/javascript" src="../e_lib/jquery-3.2.1.min.js"></script>
|
||||
<script src="js/select_npc.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
<?php
|
||||
if ($gencount >= $maxgeneral) {
|
||||
?>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
alert('더 이상 등록할 수 없습니다.');
|
||||
history.go(-1);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
die();
|
||||
}
|
||||
?>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="bg0 with_border legacy_layout">장 수 선 택<br><?=backButton()?></div>
|
||||
<table style="width:100%;" class="bg0 with_border">
|
||||
<tr><td><?=info(0)?></td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
<table style="width:100%;" class="bg0 with_border">
|
||||
<thead>
|
||||
<tr><th colspan=2 class="bg1">임관 권유 메세지</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($nations as list($name, $scoutmsg, $color)): ?>
|
||||
|
||||
<tr>
|
||||
<td style='width:98px;color:<?=newColor($color)?>;background-color:<?=$color?>'><?=$name?></td>
|
||||
<td style='color:<?=newColor($color)?>;background-color:<?=$color?>'><?=$scoutmsg?:'-'?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="bg0">
|
||||
<div class="bg1 with_border legacy_layout font1" style="text-align:center;font-weight:bold;">장수 빙의</div>
|
||||
<div class="with_border legacy_layout" style="text-align:center;">
|
||||
<small id="valid_until">(<span id="valid_until_text"></span> 까지 유효)</small><br>
|
||||
<form class="card_holder">
|
||||
</form>
|
||||
</div>
|
||||
<div class="with_border legacy_layout" style="text-align:center">
|
||||
<button id="btn_pick_more" disabled="disabled" class="with_skin with_border">다른 장수 보기</button><br>
|
||||
</div>
|
||||
<div class="with_border legacy_layout"><?=backButton()?></div>
|
||||
<div class="with_border legacy_layout"><?=banner()?></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user