feat(in-progress): 턴 조작기를 vue로 분리
This commit is contained in:
@@ -461,6 +461,36 @@ function commandGroup($typename, $type = 0)
|
||||
}
|
||||
}
|
||||
|
||||
function getCommandTable(General $general){
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->turnOnCache();
|
||||
$env = $gameStor->getAll();
|
||||
|
||||
$result = [];
|
||||
foreach (GameConst::$availableGeneralCommand as $commandCategory => $commandList) {
|
||||
$subList = [];
|
||||
foreach ($commandList as $commandClassName) {
|
||||
$commandObj = buildGeneralCommandClass($commandClassName, $general, $env);
|
||||
if (!$commandObj->canDisplay()) {
|
||||
continue;
|
||||
}
|
||||
$subList[Util::getClassNameFromObj($commandObj)] = [
|
||||
'compansation'=>$commandObj->getCompensationStyle(),
|
||||
'possible'=>$commandObj->hasMinConditionMet(),
|
||||
'title'=>$commandObj->getCommandDetailTitle(),
|
||||
];
|
||||
}
|
||||
|
||||
$result[] = [
|
||||
'category'=>$commandCategory,
|
||||
'values'=>$subList
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function printCommandTable(General $generalObj)
|
||||
{
|
||||
$db = DB::db();
|
||||
|
||||
+13
-42
@@ -104,6 +104,8 @@ $auctionCount = $db->queryFirstField('SELECT count(`no`) FROM auction');
|
||||
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
|
||||
<?= WebUtil::printJS('dist_js/vendors.js') ?>
|
||||
<?= WebUtil::printJS('d_shared/base_map.js') ?>
|
||||
<?= WebUtil::printJS('dist_js/vendors_vue.js', true) ?>
|
||||
<?= WebUtil::printJS('dist_js/v_main.js', true) ?>
|
||||
<?= WebUtil::printJS('dist_js/main.js') ?>
|
||||
<script>
|
||||
window.serverNick = '<?= DB::prefix() ?>';
|
||||
@@ -119,11 +121,18 @@ $auctionCount = $db->queryFirstField('SELECT count(`no`) FROM auction');
|
||||
}, 5000);
|
||||
});
|
||||
</script>
|
||||
<?= WebUtil::printCSS('../e_lib/bootstrap.min.css') ?>
|
||||
<?= WebUtil::printCSS('../d_shared/common.css') ?>
|
||||
<?= WebUtil::printCSS('css/common.css') ?>
|
||||
<?= WebUtil::printCSS('dist_css/common_vue.css') ?>
|
||||
<?= WebUtil::printCSS('dist_css/main.css') ?>
|
||||
<?= WebUtil::printCSS('css/map.css') ?>
|
||||
<?= WebUtil::printStaticValues([
|
||||
'maxTurn'=>GameConst::$maxTurn,
|
||||
'maxPushTurn'=>12,
|
||||
'commandList'=>getCommandTable($generalObj),
|
||||
'serverNow'=>TimeUtil::now(false),
|
||||
'baseColor2'=>GameConst::$basecolor2,
|
||||
])?>
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
|
||||
<link href="https://fonts.googleapis.com/css?family=Nanum+Gothic|Nanum+Myeongjo|Nanum+Pen+Script" rel="stylesheet">
|
||||
|
||||
@@ -233,49 +242,11 @@ $auctionCount = $db->queryFirstField('SELECT count(`no`) FROM auction');
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div id="map_view" >
|
||||
<div id="map_view">
|
||||
<div id="mapZone" class="view-item"><?= getMapHtml($mapTheme) ?></div>
|
||||
<div class="view-item" id="reservedCommandList">
|
||||
<table width="300" class="tb_layout b2">
|
||||
<thead>
|
||||
<tr height="24">
|
||||
<td colspan="4" class="center bg0"><strong>- 명령 목록 - </strong><input value="<?= TimeUtil::now(false) ?>" type="text" id="clock" size="19" style="background-color:black;color:white;border-style:none;"></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="center" style="font-weight:bold">
|
||||
<?php for ($turnIdx = 0; $turnIdx < GameConst::$maxTurn; $turnIdx++) : ?>
|
||||
<tr height='28' id="command_<?= $turnIdx ?>">
|
||||
<td width="24" class='idx_pad center bg0'><?= $turnIdx + 1 ?></td>
|
||||
<td height='24' class='month_pad center bg1' style='min-width:70px;white-space:nowrap;overflow:hidden;'></td>
|
||||
<td width='42' class='time_pad center' style='background-color:black;white-space:nowrap;overflow:hidden;'></td>
|
||||
<td width='165' class='turn_pad center bg2'><span class='turn_text'></span></td>
|
||||
</tr>
|
||||
<?php endfor; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div><?= turnTable() ?></div>
|
||||
<div>
|
||||
<span style="color:cyan"><b>←</b> Ctrl, Shift, 드래그로 복수선택 가능 반복&수정<b>→</b></span>
|
||||
<select id='repeatAmount' name=sel size=1 style=color:white;background-color:black;font-size:13px;>
|
||||
<option value=1>1턴</option>
|
||||
<option value=2>2턴</option>
|
||||
<option value=3>3턴</option>
|
||||
<option value=4>4턴</option>
|
||||
<option value=5>5턴</option>
|
||||
<option value=6>6턴</option>
|
||||
<option value=7>7턴</option>
|
||||
<option value=8>8턴</option>
|
||||
<option value=9>9턴</option>
|
||||
<option value=10>10턴</option>
|
||||
<option value=11>11턴</option>
|
||||
<option value=12>12턴</option>
|
||||
</select><input type=button value='반복' id='repeatTurn' style='background-color:<?= GameConst::$basecolor2 ?>;color:white;width:70px;font-size:13px;margin-left:1ch;margin-right:2ch;'><input type=button value='▼미루기' id='pushTurn' style='background-color:<?= GameConst::$basecolor2 ?>;color:white;width:80px;font-size:13px;'><input type=button value='▲당기기' id='pullTurn' style='background-color:<?= GameConst::$basecolor2 ?>;color:white;width:80px;font-size:13px;'>
|
||||
</div>
|
||||
<div><?php printCommandTable($generalObj) ?>
|
||||
<input type=button value='실 행' id="reserveTurn" style='background-color:<?= GameConst::$basecolor2 ?>;color:white;width:110px;font-size:13px;'><input type=button value='갱 신' id='refreshPage' style='background-color:<?= GameConst::$basecolor2 ?>;color:white;width:110px;font-size:13px;'><input type=button value='로비로' onclick="location.replace('../')" style=background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;font-size:13px;>
|
||||
</div>
|
||||
</div>
|
||||
<div class="view-item" id="reservedCommandList"></div>
|
||||
<div id="cityInfo" class="view-item" style="border:none;text-align:center;"><?= cityInfo($generalObj) ?></div>
|
||||
<div id="routeButtons" class="view-item"><input type=button value='갱 신' id='refreshPage' style='background-color:<?= GameConst::$basecolor2 ?>;color:white;width:110px;font-size:13px;'><input type=button value='로비로' onclick="location.replace('../')" style="background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;font-size:13px;"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6"><?php myNationInfo($generalObj); ?></div>
|
||||
|
||||
+52
-12
@@ -9,19 +9,22 @@ body {
|
||||
border-color: gray;
|
||||
background-position: center;
|
||||
background-repeat: repeat-y;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
@include media-breakpoint-up(md) {
|
||||
#container {
|
||||
width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(lg) {
|
||||
@include media-breakpoint-down(md) {
|
||||
body{
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#container {
|
||||
width: 100%;
|
||||
width: 500px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
@@ -33,10 +36,10 @@ body {
|
||||
}
|
||||
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
@include media-breakpoint-up(md) {
|
||||
#map_view {
|
||||
grid-template-columns: 700px 300px;
|
||||
grid-template-rows: 520px auto;
|
||||
grid-template-rows: 520px 130px auto;
|
||||
}
|
||||
|
||||
#mapZone {
|
||||
@@ -54,14 +57,24 @@ body {
|
||||
grid-row-end: 3;
|
||||
}
|
||||
|
||||
|
||||
#routeButtons{
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 2;
|
||||
grid-row-start: 3;
|
||||
grid-row-end: 4;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#reservedCommandList {
|
||||
width: 300px;
|
||||
grid-column-start: 2;
|
||||
grid-column-end: 3;
|
||||
grid-row-start: 1;
|
||||
grid-row-end: 3;
|
||||
grid-row-end: 4;
|
||||
}
|
||||
|
||||
|
||||
.buttonPlate {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(10, 1fr);
|
||||
@@ -87,7 +100,7 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(lg) {
|
||||
@include media-breakpoint-down(md) {
|
||||
.buttonPlate {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
@@ -111,6 +124,37 @@ body {
|
||||
margin: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
#mapZone {
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 2;
|
||||
grid-row-start: 1;
|
||||
grid-row-end: 2;
|
||||
}
|
||||
|
||||
|
||||
#reservedCommandList {
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 2;
|
||||
grid-row-start: 2;
|
||||
grid-row-end: 3;
|
||||
}
|
||||
|
||||
#routeButtons{
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 2;
|
||||
grid-row-start: 3;
|
||||
grid-row-end: 4;
|
||||
}
|
||||
|
||||
|
||||
#cityInfo {
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 2;
|
||||
grid-row-start: 4;
|
||||
grid-row-end: 5;
|
||||
}
|
||||
}
|
||||
|
||||
.toolbarButton {
|
||||
@@ -171,10 +215,6 @@ body {
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
#sidebar button {
|
||||
/*width:100px;*/
|
||||
}
|
||||
|
||||
.turn_pad {
|
||||
white-space: nowrap;
|
||||
font-weight: lighter;
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
<template>
|
||||
<table width="300" class="tb_layout b2">
|
||||
<thead>
|
||||
<tr height="24">
|
||||
<td colspan="4" class="center bg0">
|
||||
<strong>- 명령 목록 - </strong
|
||||
><input
|
||||
:value="serverNow"
|
||||
type="text"
|
||||
id="clock"
|
||||
size="19"
|
||||
style="background-color: black; color: white; border-style: none"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<div class="row gx-1">
|
||||
<div class="col d-grid">
|
||||
<b-dropdown right split text="당기기">
|
||||
<b-dropdown-item v-for="turnIdx in maxPushTurn" :key="turnIdx"
|
||||
>{{ turnIdx }}턴
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
</div>
|
||||
<div class="col d-grid">
|
||||
<b-dropdown right split @click="selectAll" text="전체선택">
|
||||
<b-dropdown-item @click="selectAll(true)"
|
||||
>모든턴</b-dropdown-item
|
||||
>
|
||||
<b-dropdown-item @click="selectStep(0, 2)"
|
||||
>홀수턴</b-dropdown-item
|
||||
>
|
||||
<b-dropdown-item @click="selectStep(1, 2)"
|
||||
>짝수턴</b-dropdown-item
|
||||
>
|
||||
<b-dropdown-divider></b-dropdown-divider>
|
||||
|
||||
<b-dropdown-text
|
||||
v-for="spanIdx in [3, 4, 5, 6, 7]"
|
||||
:key="spanIdx"
|
||||
>
|
||||
{{ spanIdx }}턴 간격<br />
|
||||
<b-button-group>
|
||||
<b-button
|
||||
class="ignoreMe"
|
||||
v-for="beginIdx in spanIdx"
|
||||
:key="beginIdx"
|
||||
@click="selectStep(beginIdx - 1, spanIdx)"
|
||||
>{{ beginIdx }}</b-button
|
||||
>
|
||||
</b-button-group>
|
||||
</b-dropdown-text>
|
||||
</b-dropdown>
|
||||
</div>
|
||||
<div class="col d-grid">
|
||||
<b-dropdown right text="반복">
|
||||
<b-dropdown-item v-for="turnIdx in maxPushTurn" :key="turnIdx"
|
||||
>{{ turnIdx }}턴
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="center" style="font-weight: bold">
|
||||
<tr
|
||||
v-for="turnIdx in Math.min(maxTurn, viewMaxTurn)"
|
||||
:key="turnIdx"
|
||||
height="28"
|
||||
:id="`command_${turnIdx - 1}`"
|
||||
:class="pressed[turnIdx - 1] ? 'pressed' : ''"
|
||||
>
|
||||
<td width="32" class="idx_pad center bg0 d-grid" @click="clickTurn(turnIdx - 1)">
|
||||
<b-button
|
||||
size="sm"
|
||||
:variant="pressed[turnIdx - 1] ? 'info' : 'primary'"
|
||||
>{{ turnIdx }}</b-button
|
||||
>
|
||||
</td>
|
||||
<td @click="clickTurn(turnIdx - 1)"
|
||||
height="24"
|
||||
class="month_pad center bg1"
|
||||
style="min-width: 70px; white-space: nowrap; overflow: hidden"
|
||||
></td>
|
||||
<td @click="clickTurn(turnIdx - 1)"
|
||||
width="38"
|
||||
class="time_pad center"
|
||||
style="background-color: black; white-space: nowrap; overflow: hidden"
|
||||
></td>
|
||||
<td width="160" class="turn_pad center bg2">
|
||||
<span class="turn_text"></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<div class="row gx-1">
|
||||
<div class="col-4 d-grid">
|
||||
<b-dropdown right split text="미루기">
|
||||
<b-dropdown-item v-for="turnIdx in maxPushTurn" :key="turnIdx"
|
||||
>{{ turnIdx }}턴
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
</div>
|
||||
<div class="col-8 d-grid"><b-button @click="toggleViewMaxTurn">{{flippedMaxTurn==viewMaxTurn?'펼치기':'접기'}}</b-button></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<div class="row gx-0">
|
||||
<div class="col-10 d-grid">
|
||||
<b-form-select v-model="selectedCommand"
|
||||
><b-form-select-option-group
|
||||
v-for="cgroup in commandList"
|
||||
:key="cgroup['category']"
|
||||
:label="cgroup['category']"
|
||||
><b-form-select-option v-for="(citem, ckey) in cgroup['values']" :value="ckey" :key="ckey">{{citem.title}}{{citem.possible?'':'(불가)'}}</b-form-select-option>
|
||||
</b-form-select-option-group
|
||||
></b-form-select></div>
|
||||
<div class="col-2 d-grid">
|
||||
<b-button>실행</b-button></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import addMilliseconds from "date-fns/esm/addMilliseconds/index.js";
|
||||
import { range } from "lodash";
|
||||
import { defineComponent, ref } from "vue";
|
||||
import { formatTime } from "./util/formatTime";
|
||||
import { parseTime } from "./util/parseTime";
|
||||
|
||||
type commandItem = {
|
||||
title: string;
|
||||
compensation: number;
|
||||
possible: boolean;
|
||||
};
|
||||
|
||||
declare const maxTurn: number;
|
||||
declare const maxPushTurn: number;
|
||||
declare const commandList: {
|
||||
category: string;
|
||||
values: Record<string, commandItem>[];
|
||||
}[];
|
||||
declare const serverNow: string;
|
||||
|
||||
export default defineComponent({
|
||||
name: "ReservedCommand",
|
||||
|
||||
methods: {
|
||||
updateNow() {
|
||||
const clientNow = addMilliseconds(new Date(), this.timeDiff);
|
||||
this.serverNow = formatTime(clientNow, false);
|
||||
setTimeout(() => {
|
||||
this.updateNow();
|
||||
}, 250);
|
||||
},
|
||||
clickTurn(turnIdx: number) {
|
||||
this.pressed[turnIdx] = !this.pressed[turnIdx];
|
||||
},
|
||||
selectAll(e: Event | true) {
|
||||
//NOTE: split 구현에 버그가 있어서, 수동으로 구분해야함
|
||||
if (e !== true) {
|
||||
if (!e.target) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
(e.target as HTMLElement).classList.contains("dropdown-item") ||
|
||||
(e.target as HTMLElement).classList.contains(
|
||||
"dropdown-toggle-split"
|
||||
) ||
|
||||
(e.target as HTMLElement).classList.contains("ignoreMe")
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let pressedCnt = 0;
|
||||
for (const pressed of this.pressed) {
|
||||
if (pressed) {
|
||||
pressedCnt += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (pressedCnt * 3 > this.maxTurn) {
|
||||
this.pressed.fill(false);
|
||||
} else {
|
||||
this.pressed.fill(true);
|
||||
}
|
||||
},
|
||||
selectStep(begin: number, step: number) {
|
||||
for (const idx of range(0, maxTurn)) {
|
||||
if ((idx - begin) % step == 0) {
|
||||
this.pressed[idx] = true;
|
||||
} else {
|
||||
this.pressed[idx] = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
toggleViewMaxTurn(){
|
||||
if(this.viewMaxTurn == this.flippedMaxTurn){
|
||||
this.viewMaxTurn = this.maxTurn;
|
||||
}
|
||||
else{
|
||||
this.viewMaxTurn = this.flippedMaxTurn;
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const serverNowObj = parseTime(serverNow);
|
||||
const clientNowObj = new Date();
|
||||
const timeDiff = serverNowObj.getTime() - clientNowObj.getTime();
|
||||
|
||||
setTimeout(() => {
|
||||
this.updateNow();
|
||||
}, 250);
|
||||
|
||||
const pressed = Array.from<boolean>({ length: maxTurn }).fill(false);
|
||||
pressed[0] = true;
|
||||
|
||||
const selectedCommand = ref<string>("휴식");
|
||||
|
||||
return {
|
||||
maxTurn,
|
||||
flippedMaxTurn: 18,
|
||||
viewMaxTurn: 18,
|
||||
maxPushTurn,
|
||||
commandList,
|
||||
serverNow,
|
||||
timeDiff,
|
||||
pressed,
|
||||
selectedCommand,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -13,7 +13,6 @@
|
||||
"bossInfo": "bossInfo.ts",
|
||||
"myPage": "myPage.ts",
|
||||
"extExpandCity": "extExpandCity.ts",
|
||||
"main": "main.ts",
|
||||
"dipcenter": "dipcenter.ts",
|
||||
"diplomacy": "diplomacy.ts",
|
||||
"currentCity": "currentCity.ts",
|
||||
@@ -21,12 +20,14 @@
|
||||
"history": "history.ts",
|
||||
"select_general_from_pool": "select_general_from_pool.ts",
|
||||
"extKingdoms": "extKingdoms.ts",
|
||||
"common": "common_deprecated.ts"
|
||||
"common": "common_deprecated.ts",
|
||||
"main": "main.ts"
|
||||
},
|
||||
"ingame_vue": {
|
||||
"v_inheritPoint": "v_inheritPoint.ts",
|
||||
"v_board": "v_board.ts",
|
||||
"v_NPCControl": "v_NPCControl.ts",
|
||||
"v_join": "v_join.ts"
|
||||
"v_join": "v_join.ts",
|
||||
"v_main": "v_main.ts"
|
||||
}
|
||||
}
|
||||
+7
-5
@@ -15,6 +15,9 @@ import { exportWindow } from './util/exportWindow';
|
||||
import {stringifyUrl} from 'query-string';
|
||||
import { joinYearMonth } from './util/joinYearMonth';
|
||||
import { parseYearMonth } from './util/parseYearMonth';
|
||||
|
||||
|
||||
|
||||
exportWindow($, '$');
|
||||
|
||||
import '../scss/main.scss';
|
||||
@@ -40,9 +43,8 @@ type ReservedTurnResponse = {
|
||||
autorun_limit: number|null,
|
||||
}
|
||||
|
||||
$(function ($) {
|
||||
setAxiosXMLHttpRequest();
|
||||
|
||||
$(function ($) {
|
||||
$('#refreshPage').click(function () {
|
||||
document.location.reload();
|
||||
return false;
|
||||
@@ -218,8 +220,8 @@ $(function ($) {
|
||||
window.open(href);
|
||||
});
|
||||
|
||||
setInterval(myclock, 500);
|
||||
reloadCommandList();
|
||||
//setInterval(myclock, 500);
|
||||
//reloadCommandList();
|
||||
activateFlip();
|
||||
initTooltip();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { createApp } from 'vue'
|
||||
import ReservedCommand from './ReservedCommand.vue';
|
||||
import BootstrapVue3 from 'bootstrap-vue-3'
|
||||
import { setAxiosXMLHttpRequest } from './util/setAxiosXMLHttpRequest';
|
||||
|
||||
|
||||
setAxiosXMLHttpRequest();
|
||||
|
||||
createApp(ReservedCommand).use(BootstrapVue3).mount('#reservedCommandList')
|
||||
Reference in New Issue
Block a user