Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c016621b6 | ||
|
|
f2a2b338cd | ||
|
|
715a66fd35 | ||
|
|
cc73f8c5d6 | ||
|
|
9b54b2b57d | ||
|
|
fe4d095f21 | ||
|
|
f67fa5c764 | ||
|
|
06249f29cf | ||
|
|
242efc9ae7 | ||
|
|
c86572e6f3 | ||
|
|
03b458c1b2 | ||
|
|
aa2e50366b | ||
|
|
657a47c9ad | ||
|
|
5d718bf4ea | ||
|
|
082f847b1f | ||
|
|
54e4d74d0a | ||
|
|
1437d190e5 | ||
|
|
a95b26551c | ||
|
|
c96f6d9381 | ||
|
|
c7df50d899 | ||
|
|
29619ada08 | ||
|
|
222c8a25a4 | ||
|
|
eac9b7c2e2 | ||
|
|
31d6349d71 | ||
|
|
b67f4daf3a | ||
|
|
81b81d9036 | ||
|
|
2d06f368f8 | ||
|
|
d0dc0f2bd1 | ||
|
|
e301c0fd3e | ||
|
|
5879661267 | ||
|
|
ad1f070557 | ||
|
|
c20986b7b7 | ||
|
|
153f425c99 | ||
|
|
6eb202d4b2 | ||
|
|
f7e46e16a3 | ||
|
|
36d7e22040 | ||
|
|
b24c4806f5 | ||
|
|
8ab79ad9f4 | ||
|
|
4f4533e533 | ||
|
|
e569ffe8f4 | ||
|
|
e09709651c | ||
|
|
39d7b6d55c | ||
|
|
2b2a328062 | ||
|
|
65e1495b44 | ||
|
|
3400f5843e | ||
|
|
e580691c1d | ||
|
|
bb0e817943 | ||
|
|
b7e4db6acd | ||
|
|
366fe5d613 | ||
|
|
428f2706c3 | ||
|
|
7f2b4596f7 | ||
|
|
ab9bdf3822 | ||
|
|
585667dfe8 | ||
|
|
151e6ed1f3 | ||
|
|
0685d1caac | ||
|
|
f50ba83d31 | ||
|
|
24c043386d | ||
|
|
9d868cb2f4 | ||
|
|
be308fdb4a | ||
|
|
73a5f5287b | ||
|
|
acafb15215 | ||
|
|
79b9e1b22a | ||
|
|
7ebdef3116 | ||
|
|
a3fbaa0038 | ||
|
|
fea2163a01 | ||
|
|
d55443968f | ||
|
|
b08a2681a2 | ||
|
|
48af7e5e76 | ||
|
|
98f48441c9 | ||
|
|
65f2836379 | ||
|
|
3548d4e939 | ||
|
|
eb03f34a7e | ||
|
|
40b1a9fbdf | ||
|
|
76a31acadc | ||
|
|
0f71d786f7 | ||
|
|
fec2508091 |
+16
-4
@@ -3,20 +3,23 @@ module.exports = {
|
|||||||
parser: "vue-eslint-parser",
|
parser: "vue-eslint-parser",
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"es2021": true
|
"es2021": true,
|
||||||
|
'vue/setup-compiler-macros': true
|
||||||
},
|
},
|
||||||
ignorePatterns: ['*.test.ts', '.eslintrc.cjs', 'postcss.config.cjs', 'webpack.config.cjs', '*.js'],
|
ignorePatterns: ['*.test.ts', '.eslintrc.cjs', 'postcss.config.cjs', 'webpack.config.cjs', '*.js'],
|
||||||
overrides: [{
|
overrides: [{
|
||||||
files: ['*.ts', '*.tsx', "*.vue"],
|
files: ['*.ts', '*.tsx', "*.vue"],
|
||||||
}],
|
}],
|
||||||
plugins: [
|
plugins: [
|
||||||
"@typescript-eslint"
|
"@typescript-eslint",
|
||||||
|
"prettier"
|
||||||
],
|
],
|
||||||
|
|
||||||
extends: [
|
extends: [
|
||||||
"eslint:recommended",
|
"eslint:recommended",
|
||||||
"plugin:vue/vue3-essential",
|
"plugin:vue/vue3-recommended",
|
||||||
"plugin:@typescript-eslint/recommended"
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"prettier",
|
||||||
],
|
],
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
"sourceType": "module",
|
"sourceType": "module",
|
||||||
@@ -27,6 +30,15 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
'@typescript-eslint/no-floating-promises': 'error',
|
'@typescript-eslint/no-floating-promises': 'error',
|
||||||
|
'vue/script-setup-uses-vars': 'error',
|
||||||
|
'vue/max-attributes-per-line': [
|
||||||
|
'warn',
|
||||||
|
{
|
||||||
|
singleline: 4, //prettier와 싸우지 말자
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'vue/v-on-event-hyphenation': 'off', //vue3에선 필요없다고 생각
|
||||||
|
'vue/attribute-hyphenation': 'off', //vue3에선 필요없다고 생각
|
||||||
},
|
},
|
||||||
settings: {
|
settings: {
|
||||||
'import/resolver': {
|
'import/resolver': {
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ d_setting/*.php
|
|||||||
*/d_setting/templates/*.php
|
*/d_setting/templates/*.php
|
||||||
!*.orig.php
|
!*.orig.php
|
||||||
|
|
||||||
*/data/file_cache
|
**/data/file_cache
|
||||||
|
|
||||||
**/old/*
|
**/old/*
|
||||||
test.*
|
test.*
|
||||||
|
|||||||
+1
-2
@@ -101,8 +101,7 @@ return [
|
|||||||
'hwe/j_general_set_permission.php',
|
'hwe/j_general_set_permission.php',
|
||||||
'hwe/j_get_basic_general_list.php',
|
'hwe/j_get_basic_general_list.php',
|
||||||
'hwe/j_get_city_list.php',
|
'hwe/j_get_city_list.php',
|
||||||
'hwe/j_get_general_list.php',
|
'hwe/j_get_reserved_command.php',
|
||||||
'hwe/j_get_nation_general_list.php',
|
|
||||||
'hwe/j_get_select_npc_token.php',
|
'hwe/j_get_select_npc_token.php',
|
||||||
'hwe/j_get_select_pool.php',
|
'hwe/j_get_select_pool.php',
|
||||||
'hwe/j_image_upload.php',
|
'hwe/j_image_upload.php',
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"tabWidth": 2,
|
||||||
|
"useTabs": false,
|
||||||
|
"printWidth": 120
|
||||||
|
}
|
||||||
Vendored
+2
-1
@@ -28,5 +28,6 @@
|
|||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"josa",
|
"josa",
|
||||||
"sammo"
|
"sammo"
|
||||||
]
|
],
|
||||||
|
"editor.tabSize": 2
|
||||||
}
|
}
|
||||||
@@ -8,5 +8,9 @@ require(__DIR__ . '/vendor/autoload.php');
|
|||||||
if (!class_exists('\\sammo\\RootDB')) {
|
if (!class_exists('\\sammo\\RootDB')) {
|
||||||
Json::dieWithReason('No DB');
|
Json::dieWithReason('No DB');
|
||||||
}
|
}
|
||||||
|
$eParams = $_GET;
|
||||||
|
if(key_exists('path', $eParams)){
|
||||||
|
unset($eParams['path']);
|
||||||
|
}
|
||||||
|
|
||||||
APIHelper::launch(dirname(__FILE__), $_GET['path']??null);
|
APIHelper::launch(dirname(__FILE__), $_GET['path']??'', $eParams, true);
|
||||||
@@ -172,6 +172,7 @@ if ($gameStor->isunited) {
|
|||||||
data-general-strength='{$general['strength']}'
|
data-general-strength='{$general['strength']}'
|
||||||
data-general-intel='{$general['intel']}'
|
data-general-intel='{$general['intel']}'
|
||||||
data-is-npc='" . ($general['npc'] >= 2 ? 'true' : 'false') . "'
|
data-is-npc='" . ($general['npc'] >= 2 ? 'true' : 'false') . "'
|
||||||
|
data-npc-type='{$general['npc']}'
|
||||||
>
|
>
|
||||||
<td align=center><img class='generalIcon' width='64' height='64' src='{$imageTemp}/{$general['picture']}'></img></td>
|
<td align=center><img class='generalIcon' width='64' height='64' src='{$imageTemp}/{$general['picture']}'></img></td>
|
||||||
<td align=center>$name</td>
|
<td align=center>$name</td>
|
||||||
|
|||||||
+18
-16
@@ -23,7 +23,7 @@ if ($serverID === UniqueConst::$serverID) {
|
|||||||
increaseRefresh("연감", 1);
|
increaseRefresh("연감", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$admin = $gameStor->getValues(['startyear', 'year', 'month', 'map_theme']);
|
$admin = $gameStor->getValues(['startyear', 'year', 'month']);
|
||||||
|
|
||||||
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner = %i', $userID);
|
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner = %i', $userID);
|
||||||
|
|
||||||
@@ -47,9 +47,9 @@ if ($s_year === null) {
|
|||||||
$e = Util::joinYearMonth($e_year, $e_month);
|
$e = Util::joinYearMonth($e_year, $e_month);
|
||||||
|
|
||||||
if ($serverID !== UniqueConst::$serverID) {
|
if ($serverID !== UniqueConst::$serverID) {
|
||||||
$mapTheme = $db->queryFirstField('SELECT map FROM ng_games WHERE server_id=%s', $serverID) ?: 'che';
|
$mapName = $db->queryFirstField('SELECT map FROM ng_games WHERE server_id=%s', $serverID) ?: 'che';
|
||||||
} else {
|
} else {
|
||||||
$mapTheme = $admin['map_theme'] ?? 'che';
|
$mapName = GameConst::$mapName;
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: $yearmonth가 올바르지 않을 경우에 처리가 필요.
|
//FIXME: $yearmonth가 올바르지 않을 경우에 처리가 필요.
|
||||||
@@ -104,22 +104,26 @@ $nations = $history['nations'];
|
|||||||
<meta name="viewport" content="width=1024" />
|
<meta name="viewport" content="width=1024" />
|
||||||
<title><?= UniqueConst::$serverName ?>: 연감</title>
|
<title><?= UniqueConst::$serverName ?>: 연감</title>
|
||||||
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
|
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
|
||||||
<?= WebUtil::printJS("js/map/theme_{$mapTheme}.js") ?>
|
<?= WebUtil::printJS("js/map/theme_{$mapName}.js") ?>
|
||||||
<?= WebUtil::printCSS('../d_shared/common.css') ?>
|
<?= WebUtil::printCSS('../d_shared/common.css') ?>
|
||||||
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
|
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
|
||||||
<?= WebUtil::printCSS('css/map.css') ?>
|
<?= WebUtil::printCSS('css/map.css') ?>
|
||||||
<?= WebUtil::printCSS('css/history.css') ?>
|
<?= WebUtil::printCSS('css/history.css') ?>
|
||||||
|
<?= WebUtil::printStaticValues([
|
||||||
|
'staticValues' => [
|
||||||
|
'startYear' => $s_year,
|
||||||
|
'startMonth' => $s_month,
|
||||||
|
'lastYear' => $e_year,
|
||||||
|
'lastMonth' => $e_month,
|
||||||
|
'selectYear' => $year,
|
||||||
|
'selectMonth' => $month,
|
||||||
|
'nations' => $nations ? $history['nations'] : [],
|
||||||
|
'serverNick' => DB::prefix(),
|
||||||
|
'serverID' => UniqueConst::$serverID,
|
||||||
|
]
|
||||||
|
])?>
|
||||||
<?= WebUtil::printDist('ts', ['common', 'history']) ?>
|
<?= WebUtil::printDist('ts', ['common', 'history']) ?>
|
||||||
|
|
||||||
<script>
|
|
||||||
var startYear = <?= $s_year ?>;
|
|
||||||
var startMonth = <?= $s_month ?>;
|
|
||||||
var lastYear = <?= $e_year ?>;
|
|
||||||
var lastMonth = <?= $e_month ?>;
|
|
||||||
var selectYear = <?= $year ?>;
|
|
||||||
var selectMonth = <?= $month ?>;
|
|
||||||
var nations = <?= $nations ? JSON::encode($history['nations']) : '{}' ?>;
|
|
||||||
</script>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -151,7 +155,7 @@ $nations = $history['nations'];
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr height=520>
|
<tr height=520>
|
||||||
<td width=698>
|
<td width=698>
|
||||||
<?= getMapHtml($mapTheme) ?>
|
<?= getMapHtml($mapName) ?>
|
||||||
</td>
|
</td>
|
||||||
<td id='nation_list_frame'>
|
<td id='nation_list_frame'>
|
||||||
<table id='nation_list'>
|
<table id='nation_list'>
|
||||||
@@ -204,8 +208,6 @@ $nations = $history['nations'];
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<script>
|
<script>
|
||||||
window.serverNick = '<?= DB::prefix() ?>';
|
|
||||||
window.serverID = '<?= UniqueConst::$serverID ?>';
|
|
||||||
<?php if($isCurrent): ?>
|
<?php if($isCurrent): ?>
|
||||||
reloadWorldMap({
|
reloadWorldMap({
|
||||||
showMe: false,
|
showMe: false,
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ if ($con >= 2) {
|
|||||||
}
|
}
|
||||||
$chief = $chiefs[$chiefLevel] ?? ['name' => '-', 'npc' => 0];
|
$chief = $chiefs[$chiefLevel] ?? ['name' => '-', 'npc' => 0];
|
||||||
$officerLevelText = getOfficerLevelText($chiefLevel, $nation['level']);
|
$officerLevelText = getOfficerLevelText($chiefLevel, $nation['level']);
|
||||||
$chiefText = getColoredName($chief['name'], $chief['npc']);
|
$chiefText = formatName($chief['name'], $chief['npc']);
|
||||||
echo "<td class='center bg1'>{$officerLevelText}</td>
|
echo "<td class='center bg1'>{$officerLevelText}</td>
|
||||||
<td class='center'>{$chiefText}</td>";
|
<td class='center'>{$chiefText}</td>";
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,7 @@ if ($con >= 2) {
|
|||||||
<tr>
|
<tr>
|
||||||
<td colspan=5> 장수 일람 : ";
|
<td colspan=5> 장수 일람 : ";
|
||||||
foreach ($nations[0]['generals'] as $general) {
|
foreach ($nations[0]['generals'] as $general) {
|
||||||
$generalText = getColoredName($general['name'], $general['npc']);
|
$generalText = formatName($general['name'], $general['npc']);
|
||||||
echo "{$generalText}, ";
|
echo "{$generalText}, ";
|
||||||
}
|
}
|
||||||
echo "
|
echo "
|
||||||
|
|||||||
+1
-1
@@ -111,7 +111,7 @@ $sel[$type] = "selected";
|
|||||||
</tr>
|
</tr>
|
||||||
<?php foreach ($generalList as $general) : ?>
|
<?php foreach ($generalList as $general) : ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td align=center><?= getColoredName($general['name'], $general['npc']) ?></td>
|
<td align=center><?= formatName($general['name'], $general['npc']) ?></td>
|
||||||
<td align=center><?= $general['owner_name'] ?></td>
|
<td align=center><?= $general['owner_name'] ?></td>
|
||||||
<td align=center>Lv <?= $general['explevel'] ?></td>
|
<td align=center>Lv <?= $general['explevel'] ?></td>
|
||||||
<td align=center><?= $nationName[$general['nation']] ?></td>
|
<td align=center><?= $nationName[$general['nation']] ?></td>
|
||||||
|
|||||||
+6
-1
@@ -5,4 +5,9 @@ namespace sammo;
|
|||||||
include "lib.php";
|
include "lib.php";
|
||||||
include "func.php";
|
include "func.php";
|
||||||
|
|
||||||
APIHelper::launch(dirname(__FILE__), $_GET['path']??null);
|
$eParams = $_GET;
|
||||||
|
if(key_exists('path', $eParams)){
|
||||||
|
unset($eParams['path']);
|
||||||
|
}
|
||||||
|
|
||||||
|
APIHelper::launch(dirname(__FILE__), $_GET['path']??'', $eParams, true);
|
||||||
@@ -133,7 +133,7 @@ $showGeneral = General::createGeneralObjFromDB($gen);
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<form name=form1 method=post>
|
<form name=form1 method=get>
|
||||||
정렬순서 :
|
정렬순서 :
|
||||||
<select name='query_type' size=1>
|
<select name='query_type' size=1>
|
||||||
<?php foreach ($queryMap as $queryType => [$queryTypeText,]) : ?>
|
<?php foreach ($queryMap as $queryType => [$queryTypeText,]) : ?>
|
||||||
|
|||||||
+37
-33
@@ -38,25 +38,25 @@ if ($con >= 2) {
|
|||||||
switch ($admin['tnmt_type']) {
|
switch ($admin['tnmt_type']) {
|
||||||
default:
|
default:
|
||||||
throw new \RuntimeException('Invalid tnmt_type');
|
throw new \RuntimeException('Invalid tnmt_type');
|
||||||
case 0:
|
case convertTournamentType('전력전'):
|
||||||
$tnmt_type = "<font color=cyan>전력전</font>";
|
$tnmt_type = "<font color=cyan>전력전</font>";
|
||||||
$tp = "total";
|
$tp = "total";
|
||||||
$tp2 = "종합";
|
$tp2 = "종합";
|
||||||
$tp3 = "total";
|
$tp3 = "total";
|
||||||
break;
|
break;
|
||||||
case 1:
|
case convertTournamentType('통솔전'):
|
||||||
$tnmt_type = "<font color=cyan>통솔전</font>";
|
$tnmt_type = "<font color=cyan>통솔전</font>";
|
||||||
$tp = "leadership";
|
$tp = "leadership";
|
||||||
$tp2 = "통솔";
|
$tp2 = "통솔";
|
||||||
$tp3 = "leadership";
|
$tp3 = "leadership";
|
||||||
break;
|
break;
|
||||||
case 2:
|
case convertTournamentType('일기토'):
|
||||||
$tnmt_type = "<font color=cyan>일기토</font>";
|
$tnmt_type = "<font color=cyan>일기토</font>";
|
||||||
$tp = "strength";
|
$tp = "strength";
|
||||||
$tp2 = "무력";
|
$tp2 = "무력";
|
||||||
$tp3 = "strength";
|
$tp3 = "strength";
|
||||||
break;
|
break;
|
||||||
case 3:
|
case convertTournamentType('설전'):
|
||||||
$tnmt_type = "<font color=cyan>설전</font>";
|
$tnmt_type = "<font color=cyan>설전</font>";
|
||||||
$tp = "intel";
|
$tp = "intel";
|
||||||
$tp2 = "지력";
|
$tp2 = "지력";
|
||||||
@@ -273,7 +273,7 @@ if ($str3) {
|
|||||||
for ($i = 0; $i < 8; $i++) {
|
for ($i = 0; $i < 8; $i++) {
|
||||||
$cent[$i] = "<font color=white>";
|
$cent[$i] = "<font color=white>";
|
||||||
}
|
}
|
||||||
$generalList = $db->query('SELECT npc,name,win from tournament where grp>=20 order by grp, grp_no LIMIT 16');
|
$generalList = $db->query('SELECT npc,name,win,leadership,strength,intel,leadership+strength+intel as total from tournament where grp>=20 order by grp, grp_no LIMIT 16');
|
||||||
while (count($generalList) < 16) {
|
while (count($generalList) < 16) {
|
||||||
$generalList[] = [
|
$generalList[] = [
|
||||||
'name' => '-',
|
'name' => '-',
|
||||||
@@ -293,6 +293,7 @@ if ($str3) {
|
|||||||
$line[$i] = "<font color=white>";
|
$line[$i] = "<font color=white>";
|
||||||
}
|
}
|
||||||
$gen[$i] = $general['name'];
|
$gen[$i] = $general['name'];
|
||||||
|
$stat[$i] = $general[$tp];
|
||||||
}
|
}
|
||||||
for ($i = 0; $i < 8; $i++) {
|
for ($i = 0; $i < 8; $i++) {
|
||||||
$cent[$i] = $cent[$i] . "┻" . "</font>";
|
$cent[$i] = $cent[$i] . "┻" . "</font>";
|
||||||
@@ -300,40 +301,43 @@ if ($str3) {
|
|||||||
$line[$i * 2 + 1] = $line[$i * 2 + 1] . "━━┓" . "</font>";
|
$line[$i * 2 + 1] = $line[$i * 2 + 1] . "━━┓" . "</font>";
|
||||||
echo "<td colspan=2>{$line[$i * 2]}{$cent[$i]}{$line[$i * 2 + 1]}</td>";
|
echo "<td colspan=2>{$line[$i * 2]}{$cent[$i]}{$line[$i * 2 + 1]}</td>";
|
||||||
}
|
}
|
||||||
echo "
|
|
||||||
</tr>
|
|
||||||
<tr align=center>";
|
|
||||||
|
|
||||||
for ($i = 0; $i < 16; $i++) {
|
|
||||||
echo "<td width=70>{$gen[$i]}</td>";
|
|
||||||
}
|
|
||||||
|
|
||||||
$bet = [];
|
|
||||||
$gold = [];
|
|
||||||
|
|
||||||
for ($i = 0; $i < 16; $i++) {
|
|
||||||
if ($globalBet[$i] == 0) {
|
|
||||||
$bet[$i] = "∞";
|
|
||||||
} else {
|
|
||||||
$bet[$i] = round($globalBetTotal / $globalBet[$i], 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for ($i = 0; $i < 16; $i++) {
|
|
||||||
if (!is_numeric($bet[$i])) {
|
|
||||||
$gold[$i] = 0;
|
|
||||||
} else {
|
|
||||||
$gold[$i] = Util::round($myBet[$i] * $bet[$i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
?>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr align=center>
|
||||||
|
<?php for ($i = 0; $i < 16; $i++) { ?>
|
||||||
|
<td width=70><?=$gen[$i]?></td>
|
||||||
|
<?php } ?>
|
||||||
|
</tr>
|
||||||
|
<tr align=center>
|
||||||
|
<?php for ($i = 0; $i < 16; $i++) { ?>
|
||||||
|
<td width=70 style="font-size: 14px"><?=$stat[$i]?></td>
|
||||||
|
<?php } ?>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<table align=center width=1120 class='tb_layout bg0'>
|
<table align=center width=1120 style="table-layout: fixed" class='tb_layout bg0'>
|
||||||
<tr align=center>
|
<tr align=center>
|
||||||
<td height=10 colspan=16></td>
|
<td height=10 colspan=16></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
$bet = [];
|
||||||
|
$gold = [];
|
||||||
|
|
||||||
|
for ($i = 0; $i < 16; $i++) {
|
||||||
|
if ($globalBet[$i] == 0) {
|
||||||
|
$bet[$i] = "∞";
|
||||||
|
} else {
|
||||||
|
$bet[$i] = round($globalBetTotal / $globalBet[$i], 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($i = 0; $i < 16; $i++) {
|
||||||
|
if (!is_numeric($bet[$i])) {
|
||||||
|
$gold[$i] = 0;
|
||||||
|
} else {
|
||||||
|
$gold[$i] = Util::round($myBet[$i] * $bet[$i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
echo "
|
echo "
|
||||||
<tr align=center>";
|
<tr align=center>";
|
||||||
|
|
||||||
|
|||||||
@@ -337,6 +337,7 @@ $templates = new \League\Plates\Engine('templates');
|
|||||||
'ourGeneral' => $ourGeneral,
|
'ourGeneral' => $ourGeneral,
|
||||||
'iconPath' => GetImageURL($general['imgsvr']) . '/' . $general['picture'],
|
'iconPath' => GetImageURL($general['imgsvr']) . '/' . $general['picture'],
|
||||||
'isNPC' => $isNPC,
|
'isNPC' => $isNPC,
|
||||||
|
'npc' => $general['npc'],
|
||||||
'wounded' => $wounded,
|
'wounded' => $wounded,
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'nameText' => $nameText,
|
'nameText' => $nameText,
|
||||||
@@ -364,7 +365,7 @@ $templates = new \League\Plates\Engine('templates');
|
|||||||
}
|
}
|
||||||
|
|
||||||
$generalsName = array_map(function ($gen) {
|
$generalsName = array_map(function ($gen) {
|
||||||
return getColoredName($gen['name'], $gen['npc']);
|
return formatName($gen['name'], $gen['npc']);
|
||||||
}, $generals);
|
}, $generals);
|
||||||
|
|
||||||
$enemyCrew = 0;
|
$enemyCrew = 0;
|
||||||
|
|||||||
+16
-16
@@ -13,8 +13,6 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
|
|||||||
|
|
||||||
increaseRefresh("중원정보", 1);
|
increaseRefresh("중원정보", 1);
|
||||||
|
|
||||||
$mapTheme = $gameStor->map_theme ?? 'che';
|
|
||||||
|
|
||||||
$me = $db->queryFirstRow('SELECT no,nation FROM general WHERE owner=%i', $userID);
|
$me = $db->queryFirstRow('SELECT no,nation FROM general WHERE owner=%i', $userID);
|
||||||
$myNationID = $me['nation'];
|
$myNationID = $me['nation'];
|
||||||
|
|
||||||
@@ -97,20 +95,15 @@ $neutralStateCharMap = [
|
|||||||
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
|
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
|
||||||
<?= WebUtil::printCSS('css/map.css') ?>
|
<?= WebUtil::printCSS('css/map.css') ?>
|
||||||
<?= WebUtil::printCSS('css/history.css') ?>
|
<?= WebUtil::printCSS('css/history.css') ?>
|
||||||
|
<?= WebUtil::printStaticValues([
|
||||||
|
'staticValues' => [
|
||||||
|
'serverNick' => DB::prefix(),
|
||||||
|
'serverID' => UniqueConst::$serverID,
|
||||||
|
'unitSet' => GameConst::$unitSet,
|
||||||
|
'mapName' => GameConst::$mapName,
|
||||||
|
],
|
||||||
|
]) ?>
|
||||||
<?= WebUtil::printDist('ts', ['common', 'map']) ?>
|
<?= WebUtil::printDist('ts', ['common', 'map']) ?>
|
||||||
<script>
|
|
||||||
window.serverNick = '<?= DB::prefix() ?>';
|
|
||||||
window.serverID = '<?= UniqueConst::$serverID ?>';
|
|
||||||
$(function() {
|
|
||||||
|
|
||||||
reloadWorldMap({
|
|
||||||
neutralView: true,
|
|
||||||
showMe: true,
|
|
||||||
useCachedMap: true
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -194,7 +187,7 @@ $neutralStateCharMap = [
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td width=698 height=420>
|
<td width=698 height=420>
|
||||||
<?= getMapHtml($mapTheme) ?>
|
<?= getMapHtml() ?>
|
||||||
</td>
|
</td>
|
||||||
<td id='nation_list_frame'>
|
<td id='nation_list_frame'>
|
||||||
<table id='nation_list'>
|
<table id='nation_list'>
|
||||||
@@ -231,6 +224,13 @@ $neutralStateCharMap = [
|
|||||||
<td><?= banner() ?></td>
|
<td><?= banner() ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
<script>
|
||||||
|
reloadWorldMap({
|
||||||
|
neutralView: true,
|
||||||
|
showMe: true,
|
||||||
|
useCachedMap: true
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
+1
-1
@@ -172,7 +172,7 @@ $templates = new \League\Plates\Engine('templates');
|
|||||||
|
|
||||||
$general['expLevelText'] = getExpLevel($general['experience']);
|
$general['expLevelText'] = getExpLevel($general['experience']);
|
||||||
|
|
||||||
$general['nameText'] = getColoredName($general['name'], $general['npc']);
|
$general['nameText'] = formatName($general['name'], $general['npc']);
|
||||||
|
|
||||||
$general['modeText'] = formatDefenceTrain($general['defence_train']);
|
$general['modeText'] = formatDefenceTrain($general['defence_train']);
|
||||||
$general['crewtypeText'] = GameUnitConst::byId($general['crewtype'])->name ?? '-';
|
$general['crewtypeText'] = GameUnitConst::byId($general['crewtype'])->name ?? '-';
|
||||||
|
|||||||
+72
-58
@@ -71,7 +71,8 @@ $sel = [$type => "selected"];
|
|||||||
</table>
|
</table>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$nation = getNationStaticInfo($me['nation']); //국가정보
|
$nation = $db->queryFirstRow('SELECT nation, name, color, type, level, capital, gennum, `power`, `rate` from nation WHERE nation = %i', $nationID); //국가정보
|
||||||
|
$nationTypeObj = buildNationTypeClass($nation['type']);
|
||||||
|
|
||||||
$officerList = [];
|
$officerList = [];
|
||||||
foreach ($db->query('SELECT no,name,npc,city,officer_level,officer_city,belong FROM general WHERE nation = %i AND 2 <= officer_level AND officer_level <= 4', $nationID) as $officer) {
|
foreach ($db->query('SELECT no,name,npc,city,officer_level,officer_city,belong FROM general WHERE nation = %i AND 2 <= officer_level AND officer_level <= 4', $nationID) as $officer) {
|
||||||
@@ -82,6 +83,17 @@ $sel = [$type => "selected"];
|
|||||||
$officerList[$officerCityID][$officer['officer_level']] = $officer;
|
$officerList[$officerCityID][$officer['officer_level']] = $officer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$generalList = $db->query('SELECT npc, name, city FROM general WHERE nation = %i', $me['nation']);
|
||||||
|
$cityGeneralList = [];
|
||||||
|
foreach ($generalList as $general) {
|
||||||
|
$cityID = $general['city'];
|
||||||
|
if (!key_exists($cityID, $cityGeneralList)) {
|
||||||
|
$cityGeneralList[$cityID] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$cityGeneralList[$cityID][] = formatName($general['name'], $general['npc']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$cityList = $db->query('SELECT *,pop/pop_max as poprate from city where nation=%i', $nationID);
|
$cityList = $db->query('SELECT *,pop/pop_max as poprate from city where nation=%i', $nationID);
|
||||||
|
|
||||||
@@ -171,8 +183,12 @@ $sel = [$type => "selected"];
|
|||||||
];
|
];
|
||||||
|
|
||||||
$cityOfficerList = $officerList[$cityID] ?? [];
|
$cityOfficerList = $officerList[$cityID] ?? [];
|
||||||
|
$effectiveOfficerCnt = 0;
|
||||||
foreach ($cityOfficerList as $cityOfficer) {
|
foreach ($cityOfficerList as $cityOfficer) {
|
||||||
$officerName[$cityOfficer['officer_level']] = getColoredName($cityOfficer['name'], $cityOfficer['npc']);
|
if ($cityOfficer['city'] == $cityID) {
|
||||||
|
$effectiveOfficerCnt += 1;
|
||||||
|
}
|
||||||
|
$officerName[$cityOfficer['officer_level']] = formatName($cityOfficer['name'], $cityOfficer['npc']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($type == 10 && $city['region'] != $region) {
|
if ($type == 10 && $city['region'] != $region) {
|
||||||
@@ -187,62 +203,60 @@ $sel = [$type => "selected"];
|
|||||||
$city['trade'] = "- ";
|
$city['trade'] = "- ";
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "
|
|
||||||
<table align=center width=1000 class='tb_layout bg2'>
|
$cityGoldIncome = $nation['rate'] / 20 * calcCityGoldIncome($city, $effectiveOfficerCnt, $nation['capital'] == $cityID, $nation['level'], $nationTypeObj);
|
||||||
<tr>
|
$cityRiceIncome = $nation['rate'] / 20 * calcCityRiceIncome($city, $effectiveOfficerCnt, $nation['capital'] == $cityID, $nation['level'], $nationTypeObj);
|
||||||
<td colspan=12 style=color:" . newColor($nation['color']) . "; bgcolor={$nation['color']}><font size=2>【 " . CityConst::$regionMap[$city['region']] . " | " . CityConst::$levelMap[$city['level']] . " 】 {$city['name']}</font></td>
|
$cityWallIncome = $nation['rate'] / 20 * calcCityWallRiceIncome($city, $effectiveOfficerCnt, $nation['capital'] == $cityID, $nation['level'], $nationTypeObj);
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align=center width=46 class='bg1'>주민</td>
|
|
||||||
<td align=center width=140>{$city['pop']}/{$city['pop_max']}</td>
|
|
||||||
<td align=center width=46 class='bg1'>농업</td>
|
|
||||||
<td align=center width=140>{$city['agri']}/{$city['agri_max']}</td>
|
|
||||||
<td align=center width=46 class='bg1'>상업</td>
|
|
||||||
<td align=center width=140>{$city['comm']}/{$city['comm_max']}</td>
|
|
||||||
<td align=center width=46 class='bg1'>치안</td>
|
|
||||||
<td align=center width=140>{$city['secu']}/{$city['secu_max']}</td>
|
|
||||||
<td align=center width=46 class='bg1'>수비</td>
|
|
||||||
<td align=center width=140>{$city['def']}/{$city['def_max']}</td>
|
|
||||||
<td align=center width=46 class='bg1'>성벽</td>
|
|
||||||
<td align=center width=140>{$city['wall']}/{$city['wall_max']}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align=center class='bg1'>민심</td>
|
|
||||||
<td align=center>" . round($city['trust'], 1) . "</td>
|
|
||||||
<td align=center class='bg1'>시세</td>
|
|
||||||
<td align=center>{$city['trade']}%</td>
|
|
||||||
<td align=center class='bg1'>인구</td>
|
|
||||||
<td align=center>" . round($city['pop'] / $city['pop_max'] * 100, 2) . " %</td>
|
|
||||||
<td align=center class='bg1'>태수</td>
|
|
||||||
<td align=center>";
|
|
||||||
echo $officerName[4];
|
|
||||||
echo "</td>
|
|
||||||
<td align=center class='bg1'>군사</td>
|
|
||||||
<td align=center>";
|
|
||||||
echo $officerName[3];
|
|
||||||
echo "</td>
|
|
||||||
<td align=center class='bg1'>종사</td>
|
|
||||||
<td align=center>";
|
|
||||||
echo $officerName[2];
|
|
||||||
echo "</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align=center class='bg1'>장수</td>
|
|
||||||
<td colspan=11>";
|
|
||||||
$generalList = $db->query('SELECT npc, name FROM general WHERE city = %i AND nation = %i', $city['city'], $me['nation']);
|
|
||||||
if (!$generalList) {
|
|
||||||
echo "-";
|
|
||||||
}
|
|
||||||
foreach ($generalList as $general) {
|
|
||||||
echo getColoredName($general['name'], $general['npc']) . ', ';
|
|
||||||
}
|
|
||||||
echo "
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
";
|
|
||||||
}
|
|
||||||
?>
|
?>
|
||||||
|
<table align=center width=1000 class='tb_layout bg2'>
|
||||||
|
<tr>
|
||||||
|
<td colspan=10 style="color:<?= newColor($nation['color']) ?>; background-color:<?= $nation['color'] ?>;">
|
||||||
|
<font size=2>【 <?= CityConst::$regionMap[$city['region']] ?> | <?= CityConst::$levelMap[$city['level']] ?> 】 <?= $city['name'] ?></font>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr style='text-align:center;'>
|
||||||
|
<td width=60 class='bg1'>주민</td>
|
||||||
|
<td width=140 class='pop-value'><?= $city['pop'] ?>/<?= $city['pop_max'] ?></td>
|
||||||
|
<td width=60 class='bg1'>인구율</td>
|
||||||
|
<td width=140 class='pop-prop-value'><?= round($city['pop'] / $city['pop_max'] * 100, 2) ?>%</td>
|
||||||
|
<td width=60 class='bg1'>자금 수입</td>
|
||||||
|
<td width=140 class='gold-income'><?= number_format($cityGoldIncome) ?></td>
|
||||||
|
<td width=60 class='bg1'>군량 수입</td>
|
||||||
|
<td width=140 class='rice-income'><?= number_format($cityRiceIncome) ?></td>
|
||||||
|
<td width=60 class='bg1'>둔전 수입</td>
|
||||||
|
<td width=140 class='wall-income'><?= number_format($cityWallIncome) ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr style='text-align:center;'>
|
||||||
|
<td class='bg1'>농업</td>
|
||||||
|
<td class='agri-value'><?= $city['agri'] ?>/<?= $city['agri_max'] ?></td>
|
||||||
|
<td class='bg1'>상업</td>
|
||||||
|
<td class='comm-value'><?= $city['comm'] ?>/<?= $city['comm_max'] ?></td>
|
||||||
|
<td class='bg1'>치안</td>
|
||||||
|
<td class='secu-value'><?= $city['secu'] ?>/<?= $city['secu_max'] ?></td>
|
||||||
|
<td class='bg1'>수비</td>
|
||||||
|
<td class='def-value'><?= $city['def'] ?>/<?= $city['def_max'] ?></td>
|
||||||
|
<td class='bg1'>성벽</td>
|
||||||
|
<td class='wall-value'><?= $city['wall'] ?>/<?= $city['wall_max'] ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr style='text-align:center;'>
|
||||||
|
<td class='bg1'>민심</td>
|
||||||
|
<td class='trust-value'><?= round($city['trust'], 1) ?></td>
|
||||||
|
<td class='bg1'>시세</td>
|
||||||
|
<td class='trade-value'><?= $city['trade'] ?>%</td>
|
||||||
|
<td class='bg1'>태수</td>
|
||||||
|
<td class='officer-4-value'><?= $officerName[4] ?></td>
|
||||||
|
<td class='bg1'>군사</td>
|
||||||
|
<td class='officer-3-value'><?= $officerName[3] ?></td>
|
||||||
|
<td class='bg1'>종사</td>
|
||||||
|
<td class='officer-2-value'><?= $officerName[2] ?></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style='text-align:center;' class='bg1'>장수</td>
|
||||||
|
<td colspan=9 class='city-generals'><?= key_exists($cityID, $cityGeneralList) ? join(', ', $cityGeneralList[$cityID]) : '-' ?></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
<table align=center width=1000 class='tb_layout bg0 anchor'>
|
<table align=center width=1000 class='tb_layout bg0 anchor'>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -252,7 +266,7 @@ $sel = [$type => "selected"];
|
|||||||
<td><?= banner() ?></td>
|
<td><?= banner() ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
<div id="helper_genlist" style="display:none;"></div>
|
||||||
</body>
|
</body>
|
||||||
<div id="helper_genlist" style="display:none;"></div>
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -98,8 +98,8 @@ if($btn == '참가') {
|
|||||||
], 'no=%i', $general['no']);
|
], 'no=%i', $general['no']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$grpCount = $db->queryFirstField('SELECT count(*) FROM tournament where grp<10 GROUP BY grp HAVING count(*)=8');
|
$grpCount = $db->queryFirstColumn('SELECT count(grp) FROM tournament where grp<10 GROUP BY grp;');
|
||||||
if($grpCount >= 8) {
|
if(min($grpCount) >= 8) {
|
||||||
$gameStor->tournament = 2;
|
$gameStor->tournament = 2;
|
||||||
$gameStor->phase = 0;
|
$gameStor->phase = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -171,7 +171,7 @@ function cityInfo(General $generalObj)
|
|||||||
];
|
];
|
||||||
|
|
||||||
foreach ($db->query('SELECT `officer_level`, `name`, npc, no FROM general WHERE officer_city = %i', $cityID) as $officer) {
|
foreach ($db->query('SELECT `officer_level`, `name`, npc, no FROM general WHERE officer_city = %i', $cityID) as $officer) {
|
||||||
$officerName[$officer['officer_level']] = getColoredName($officer['name'], $officer['npc']);
|
$officerName[$officer['officer_level']] = formatName($officer['name'], $officer['npc']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$city['officerName'] = $officerName;
|
$city['officerName'] = $officerName;
|
||||||
@@ -199,8 +199,8 @@ function myNationInfo(General $generalObj)
|
|||||||
|
|
||||||
$topChiefs = Util::convertArrayToDict($db->query('SELECT officer_level, no, name, npc FROM general WHERE nation = %i AND officer_level >= 11', $nationID), 'officer_level');
|
$topChiefs = Util::convertArrayToDict($db->query('SELECT officer_level, no, name, npc FROM general WHERE nation = %i AND officer_level >= 11', $nationID), 'officer_level');
|
||||||
|
|
||||||
$level12Name = key_exists(12, $topChiefs) ? getColoredName($topChiefs[12]['name'], $topChiefs[12]['npc']) : '-';
|
$level12Name = key_exists(12, $topChiefs) ? formatName($topChiefs[12]['name'], $topChiefs[12]['npc']) : '-';
|
||||||
$level11Name = key_exists(11, $topChiefs) ? getColoredName($topChiefs[11]['name'], $topChiefs[11]['npc']) : '-';
|
$level11Name = key_exists(11, $topChiefs) ? formatName($topChiefs[11]['name'], $topChiefs[11]['npc']) : '-';
|
||||||
|
|
||||||
$impossibleStrategicCommandLists = [];
|
$impossibleStrategicCommandLists = [];
|
||||||
$strategicCommandLists = GameConst::$availableChiefCommand['전략'];
|
$strategicCommandLists = GameConst::$availableChiefCommand['전략'];
|
||||||
|
|||||||
@@ -393,6 +393,7 @@ function setGeneralCommand(int $generalID, array $rawTurnList, string $command,
|
|||||||
_setGeneralCommand($commandObj, $turnList);
|
_setGeneralCommand($commandObj, $turnList);
|
||||||
return [
|
return [
|
||||||
'result'=>true,
|
'result'=>true,
|
||||||
|
'brief'=>$commandObj->getBrief(),
|
||||||
'reason'=>'success'
|
'reason'=>'success'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -474,6 +475,7 @@ function setNationCommand(int $generalID, array $turnList, string $command, ?arr
|
|||||||
_setNationCommand($commandObj, $turnList);
|
_setNationCommand($commandObj, $turnList);
|
||||||
return [
|
return [
|
||||||
'result'=>true,
|
'result'=>true,
|
||||||
|
'brief'=>$commandObj->getBrief(),
|
||||||
'arg_test'=>true,
|
'arg_test'=>true,
|
||||||
'reason'=>'success'
|
'reason'=>'success'
|
||||||
];
|
];
|
||||||
|
|||||||
+31
-8
@@ -64,6 +64,15 @@ function getNationLevel(int $level) {
|
|||||||
][$level];
|
][$level];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function convertTournamentType(string $type){
|
||||||
|
return[
|
||||||
|
'전력전'=>0,
|
||||||
|
'통솔전'=>1,
|
||||||
|
'일기토'=>2,
|
||||||
|
'설전'=>3,
|
||||||
|
][$type]??-1;
|
||||||
|
}
|
||||||
|
|
||||||
function getGenChar(?string $type) {
|
function getGenChar(?string $type) {
|
||||||
if($type === null){
|
if($type === null){
|
||||||
return '-';
|
return '-';
|
||||||
@@ -692,21 +701,35 @@ function isConsumable(?string $item) : bool{
|
|||||||
return $itemClass->isConsumable();
|
return $itemClass->isConsumable();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNameColor(int $npcType):?string{
|
function getNPCColor(int $npc): ?string{
|
||||||
if($npcType >= 2){
|
if ($npc == 1) {
|
||||||
return 'cyan';
|
|
||||||
}
|
|
||||||
if($npcType == 1){
|
|
||||||
return 'skyblue';
|
return 'skyblue';
|
||||||
}
|
}
|
||||||
|
if ($npc == 4){
|
||||||
|
return 'deepskyblue';
|
||||||
|
}
|
||||||
|
if ($npc == 5){
|
||||||
|
return 'darkcyan';
|
||||||
|
}
|
||||||
|
if ($npc == 6){
|
||||||
|
return 'mediumaquamarine';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($npc > 1) {
|
||||||
|
return 'cyan';
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
function getColoredName(string $name, int $npcType):string{
|
|
||||||
$color = getNameColor($npcType);
|
function formatName(string $name, int $npc): string
|
||||||
|
{
|
||||||
|
$color = getNPCColor($npc);
|
||||||
if($color === null){
|
if($color === null){
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
return "<span style='color:{$color}'>{$name}</span>";
|
|
||||||
|
return "<span style='color:{$color}'>$name</span>";
|
||||||
}
|
}
|
||||||
|
|
||||||
function ConvertLog(?string $str, $type=1) : string {
|
function ConvertLog(?string $str, $type=1) : string {
|
||||||
|
|||||||
@@ -371,7 +371,7 @@ function postUpdateMonthly()
|
|||||||
sum(pop)*sum(pop+agri+comm+secu+wall+def)/sum(pop_max+agri_max+comm_max+secu_max+wall_max+def_max)/100
|
sum(pop)*sum(pop+agri+comm+secu+wall+def)/sum(pop_max+agri_max+comm_max+secu_max+wall_max+def_max)/100
|
||||||
) from city where nation=A.nation and supply=1
|
) from city where nation=A.nation and supply=1
|
||||||
))
|
))
|
||||||
+(select SUM((ra.value + 1000)/(rb.value + 1000)*(CASE WHEN g.`leadership` >= 40 THEN g.`leadership` ELSE 0 END)*2 + (SQRT(g.intel * g.strength) * 2 + g.leadership / 2)/2)
|
+(select SUM((ra.value + 1000)/(rb.value + 1000)*(CASE WHEN g.`npc` < 2 THEN 1.2 ELSE 1 END)*(CASE WHEN g.`leadership` >= 40 THEN g.`leadership` ELSE 0 END)*2 + (SQRT(g.intel * g.strength) * 2 + g.leadership / 2)/2)
|
||||||
FROM general AS g
|
FROM general AS g
|
||||||
LEFT JOIN `rank_data` AS ra ON g.`no` = ra.general_id AND ra.`type` = \'killcrew_person\'
|
LEFT JOIN `rank_data` AS ra ON g.`no` = ra.general_id AND ra.`type` = \'killcrew_person\'
|
||||||
LEFT JOIN `rank_data` AS rb ON g.`no` = rb.general_id AND rb.`type` = \'deathcrew_person\'
|
LEFT JOIN `rank_data` AS rb ON g.`no` = rb.general_id AND rb.`type` = \'deathcrew_person\'
|
||||||
|
|||||||
+6
-40
@@ -168,7 +168,7 @@ function commandButton(array $opts = [])
|
|||||||
$showSecret = false;
|
$showSecret = false;
|
||||||
$permission = checkSecretPermission($me);
|
$permission = checkSecretPermission($me);
|
||||||
$btnClassForTournament = $opts['btnClass'];
|
$btnClassForTournament = $opts['btnClass'];
|
||||||
if ($opts['isTournamentActive']) {
|
if ($opts['isTournamentApplicationOpen']) {
|
||||||
if ($btnClassForTournament != 'dropdown-item') {
|
if ($btnClassForTournament != 'dropdown-item') {
|
||||||
$btnClassForTournament = 'toolbarButton2';
|
$btnClassForTournament = 'toolbarButton2';
|
||||||
}
|
}
|
||||||
@@ -231,57 +231,23 @@ function formatLeadershipBonus(int $value): string
|
|||||||
return "<font color=cyan>+{$value}</font>";
|
return "<font color=cyan>+{$value}</font>";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNPCColor(int $npc): ?string{
|
|
||||||
if ($npc == 1) {
|
|
||||||
return 'skyblue';
|
|
||||||
}
|
|
||||||
if ($npc == 4){
|
|
||||||
return 'deepskyblue';
|
|
||||||
}
|
|
||||||
if ($npc == 5){
|
|
||||||
return 'darkcyan';
|
|
||||||
}
|
|
||||||
if ($npc == 6){
|
|
||||||
return 'mediumaquamarine';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($npc > 1) {
|
|
||||||
return 'cyan';
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatName(string $name, int $npc): string
|
|
||||||
{
|
|
||||||
$color = getNPCColor($npc);
|
|
||||||
if($color === null){
|
|
||||||
return $name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "<span style='color:{$color}'>$name</span>";
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMapTheme(): string
|
function getMapTheme(): string
|
||||||
{
|
{
|
||||||
$db = DB::db();
|
return GameConst::$mapName;
|
||||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
|
||||||
$mapTheme = $gameStor->map_theme ?? 'che';
|
|
||||||
return $mapTheme;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMapHtml(?string $mapTheme = null)
|
function getMapHtml(?string $mapName = null)
|
||||||
{
|
{
|
||||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||||
|
|
||||||
if ($mapTheme === null) {
|
if($mapName === null){
|
||||||
$db = DB::db();
|
$mapName = GameConst::$mapName;
|
||||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
|
||||||
$mapTheme = $gameStor->map_theme ?? 'che';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $templates->render('map', [
|
return $templates->render('map', [
|
||||||
'mapTheme' => $mapTheme
|
'mapName' => $mapName
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-19
@@ -4,14 +4,12 @@ namespace sammo;
|
|||||||
* 시간 단위로 일어나는 이벤트들에 대한 함수 모음
|
* 시간 단위로 일어나는 이벤트들에 대한 함수 모음
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
//1월마다 실행
|
//1월마다 실행
|
||||||
function processSpring() {
|
function processSpring() {
|
||||||
$db = DB::db();
|
$db = DB::db();
|
||||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||||
|
|
||||||
//인구 증가
|
|
||||||
popIncrease();
|
|
||||||
// 1월엔 무조건 내정 1% 감소
|
// 1월엔 무조건 내정 1% 감소
|
||||||
$db->update('city',[
|
$db->update('city',[
|
||||||
'dead'=>0,
|
'dead'=>0,
|
||||||
@@ -22,6 +20,9 @@ function processSpring() {
|
|||||||
'wall'=>$db->sqleval('wall * 0.99'),
|
'wall'=>$db->sqleval('wall * 0.99'),
|
||||||
],true);
|
],true);
|
||||||
|
|
||||||
|
//인구 증가
|
||||||
|
popIncrease();
|
||||||
|
|
||||||
// > 10000 유지비 3%, > 1000 유지비 1%
|
// > 10000 유지비 3%, > 1000 유지비 1%
|
||||||
// 유지비 1%
|
// 유지비 1%
|
||||||
$db->update('general', [
|
$db->update('general', [
|
||||||
@@ -100,7 +101,7 @@ function processGoldIncome() {
|
|||||||
$generalObj = new General($rawGeneral, null, null, null, $year, $month, false);
|
$generalObj = new General($rawGeneral, null, null, null, $year, $month, false);
|
||||||
$gold = Util::round(getBill($generalObj->getVar('dedication'))*$ratio);
|
$gold = Util::round(getBill($generalObj->getVar('dedication'))*$ratio);
|
||||||
$generalObj->increaseVar('gold', $gold);
|
$generalObj->increaseVar('gold', $gold);
|
||||||
|
|
||||||
$logger = $generalObj->getLogger();
|
$logger = $generalObj->getLogger();
|
||||||
if($generalObj->getVar('officer_level') > 4){
|
if($generalObj->getVar('officer_level') > 4){
|
||||||
$logger->pushGeneralActionLog($incomeLog, $logger::PLAIN);
|
$logger->pushGeneralActionLog($incomeLog, $logger::PLAIN);
|
||||||
@@ -121,9 +122,9 @@ function processGoldIncome() {
|
|||||||
|
|
||||||
function popIncrease() {
|
function popIncrease() {
|
||||||
$db = DB::db();
|
$db = DB::db();
|
||||||
|
|
||||||
$nationList = $db->queryAllLists('SELECT nation,rate_tmp,type FROM nation');
|
$nationList = $db->queryAllLists('SELECT nation,rate_tmp,type FROM nation');
|
||||||
|
|
||||||
// 인구 및 민심
|
// 인구 및 민심
|
||||||
|
|
||||||
$db->update('city', [
|
$db->update('city', [
|
||||||
@@ -138,7 +139,7 @@ function popIncrease() {
|
|||||||
foreach($nationList as [$nationID, $taxRate, $nationType]){
|
foreach($nationList as [$nationID, $taxRate, $nationType]){
|
||||||
$nationTypeObj = buildNationTypeClass($nationType);
|
$nationTypeObj = buildNationTypeClass($nationType);
|
||||||
|
|
||||||
|
|
||||||
$popRatio = (30 - $taxRate)/200; // 20일때 5% 5일때 12.5% 50일때 -10%
|
$popRatio = (30 - $taxRate)/200; // 20일때 5% 5일때 12.5% 50일때 -10%
|
||||||
$popRatio = $nationTypeObj->onCalcNationalIncome('pop', $popRatio);
|
$popRatio = $nationTypeObj->onCalcNationalIncome('pop', $popRatio);
|
||||||
|
|
||||||
@@ -246,7 +247,7 @@ function getGoldIncome(int $nationID, int $nationLevel, float $taxRate, int $cap
|
|||||||
}
|
}
|
||||||
|
|
||||||
$cityIncome *= ($taxRate / 20);
|
$cityIncome *= ($taxRate / 20);
|
||||||
|
|
||||||
return $cityIncome;
|
return $cityIncome;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,9 +291,6 @@ function getWarGoldIncome(string $nationType, array $cityList){
|
|||||||
function processFall() {
|
function processFall() {
|
||||||
$db = DB::db();
|
$db = DB::db();
|
||||||
|
|
||||||
//인구 증가
|
|
||||||
popIncrease();
|
|
||||||
|
|
||||||
// 7월엔 무조건 내정 1% 감소
|
// 7월엔 무조건 내정 1% 감소
|
||||||
$db->update('city',[
|
$db->update('city',[
|
||||||
'dead'=>0,
|
'dead'=>0,
|
||||||
@@ -303,6 +301,8 @@ function processFall() {
|
|||||||
'wall'=>$db->sqleval('wall * 0.99'),
|
'wall'=>$db->sqleval('wall * 0.99'),
|
||||||
],true);
|
],true);
|
||||||
|
|
||||||
|
//인구 증가
|
||||||
|
popIncrease();
|
||||||
|
|
||||||
// > 10000 유지비 3%, > 1000 유지비 1%
|
// > 10000 유지비 3%, > 1000 유지비 1%
|
||||||
// 유지비 1%
|
// 유지비 1%
|
||||||
@@ -378,7 +378,7 @@ function processRiceIncome() {
|
|||||||
$generalObj = new General($rawGeneral, null, null, null, $year, $month, false);
|
$generalObj = new General($rawGeneral, null, null, null, $year, $month, false);
|
||||||
$rice = Util::round(getBill($generalObj->getVar('dedication'))*$ratio);
|
$rice = Util::round(getBill($generalObj->getVar('dedication'))*$ratio);
|
||||||
$generalObj->increaseVar('rice', $rice);
|
$generalObj->increaseVar('rice', $rice);
|
||||||
|
|
||||||
$logger = $generalObj->getLogger();
|
$logger = $generalObj->getLogger();
|
||||||
if($generalObj->getVar('officer_level') > 4){
|
if($generalObj->getVar('officer_level') > 4){
|
||||||
$logger->pushGeneralActionLog($incomeLog, $logger::PLAIN);
|
$logger->pushGeneralActionLog($incomeLog, $logger::PLAIN);
|
||||||
@@ -418,7 +418,7 @@ function getRiceIncome(int $nationID, int $nationLevel, float $taxRate, int $cap
|
|||||||
}
|
}
|
||||||
|
|
||||||
$cityIncome *= ($taxRate / 20);
|
$cityIncome *= ($taxRate / 20);
|
||||||
|
|
||||||
return $cityIncome;
|
return $cityIncome;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,12 +439,12 @@ function getWallIncome(int $nationID, int $nationLevel, float $taxRate, int $cap
|
|||||||
$cityIncome = 0;
|
$cityIncome = 0;
|
||||||
foreach($cityList as $rawCity){
|
foreach($cityList as $rawCity){
|
||||||
$cityID = $rawCity['city'];
|
$cityID = $rawCity['city'];
|
||||||
|
|
||||||
$cityIncome += calcCityWallRiceIncome($rawCity, $officersCnt[$cityID]??0, $capitalID == $cityID, $nationLevel, $nationTypeObj);
|
$cityIncome += calcCityWallRiceIncome($rawCity, $officersCnt[$cityID]??0, $capitalID == $cityID, $nationLevel, $nationTypeObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
$cityIncome *= ($taxRate / 20);
|
$cityIncome *= ($taxRate / 20);
|
||||||
|
|
||||||
return $cityIncome;
|
return $cityIncome;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,7 +520,7 @@ function disaster() {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$raiseProp = 0.06 - ($city['secu'] / $city['secu_max']) * 0.05; // 1 ~ 6%
|
$raiseProp = 0.06 - ($city['secu'] / $city['secu_max']) * 0.05; // 1 ~ 6%
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Util::randBool($raiseProp)) {
|
if(Util::randBool($raiseProp)) {
|
||||||
$targetCityList[] = $city;
|
$targetCityList[] = $city;
|
||||||
@@ -592,11 +592,11 @@ function disaster() {
|
|||||||
'def'=>$db->sqleval('def * %d', $affectRatio),
|
'def'=>$db->sqleval('def * %d', $affectRatio),
|
||||||
'wall'=>$db->sqleval('wall * %d', $affectRatio),
|
'wall'=>$db->sqleval('wall * %d', $affectRatio),
|
||||||
], 'city = %i', $city['city']);
|
], 'city = %i', $city['city']);
|
||||||
|
|
||||||
$generalList = array_map(
|
$generalList = array_map(
|
||||||
function($rawGeneral) use ($city, $year, $month){
|
function($rawGeneral) use ($city, $year, $month){
|
||||||
return new General($rawGeneral, null, $city, null, $year, $month, false);
|
return new General($rawGeneral, null, $city, null, $year, $month, false);
|
||||||
},
|
},
|
||||||
$generalListByCity[$city['city']]??[]
|
$generalListByCity[$city['city']]??[]
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -619,7 +619,7 @@ function disaster() {
|
|||||||
'wall'=>$db->sqleval('least(wall * %d, wall_max)', $affectRatio),
|
'wall'=>$db->sqleval('least(wall * %d, wall_max)', $affectRatio),
|
||||||
], 'city = %i', $city['city']);
|
], 'city = %i', $city['city']);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
-8
@@ -83,12 +83,12 @@ if ($gameStor->npcmode == 0) {
|
|||||||
$npcmode = "선택 생성";
|
$npcmode = "선택 생성";
|
||||||
}
|
}
|
||||||
$color = "cyan";
|
$color = "cyan";
|
||||||
$mapTheme = $gameStor->map_theme;
|
|
||||||
$serverName = UniqueConst::$serverName;
|
$serverName = UniqueConst::$serverName;
|
||||||
$serverCnt = $gameStor->server_cnt;
|
$serverCnt = $gameStor->server_cnt;
|
||||||
|
|
||||||
$auctionCount = $db->queryFirstField('SELECT count(`no`) FROM auction');
|
$auctionCount = $db->queryFirstField('SELECT count(`no`) FROM auction');
|
||||||
$isTournamentActive = $gameStor->tournament == 1;
|
$isTournamentActive = $gameStor->tournament > 0;
|
||||||
|
$isTournamentApplicationOpen = $gameStor->tournament == 1;
|
||||||
$isBettingActive = $gameStor->tournament == 6;
|
$isBettingActive = $gameStor->tournament == 6;
|
||||||
|
|
||||||
$myNationStatic = getNationStaticInfo($generalObj->getNationID());
|
$myNationStatic = getNationStaticInfo($generalObj->getNationID());
|
||||||
@@ -125,19 +125,34 @@ if (!$otherTextInfo) {
|
|||||||
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
|
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
|
||||||
<?= WebUtil::printCSS('css/map.css') ?>
|
<?= WebUtil::printCSS('css/map.css') ?>
|
||||||
<?= WebUtil::printStaticValues([
|
<?= WebUtil::printStaticValues([
|
||||||
|
//deprecated, staticValues를 이용할 것
|
||||||
'serverName' => $serverName,
|
'serverName' => $serverName,
|
||||||
'serverCnt' => $serverCnt,
|
'serverCnt' => $serverCnt,
|
||||||
'serverNick' => DB::prefix(),
|
'serverNick' => DB::prefix(),
|
||||||
'serverID' => UniqueConst::$serverID,
|
'serverID' => UniqueConst::$serverID,
|
||||||
'maxTurn' => GameConst::$maxTurn,
|
'maxTurn' => GameConst::$maxTurn,
|
||||||
'maxPushTurn' => 12,
|
'maxPushTurn' => 12,
|
||||||
'commandList' => getCommandTable($generalObj),
|
|
||||||
'serverNow' => TimeUtil::now(false),
|
'serverNow' => TimeUtil::now(false),
|
||||||
'baseColor2' => GameConst::$basecolor2,
|
|
||||||
'lastExecuted' => $gameStor->turntime,
|
'lastExecuted' => $gameStor->turntime,
|
||||||
'isLocked' => $plock,
|
'isLocked' => $plock,
|
||||||
'isTournamentActive' => $isTournamentActive,
|
'isTournamentActive' => $isTournamentActive,
|
||||||
'isBettingActive' => $isBettingActive
|
'isBettingActive' => $isBettingActive,
|
||||||
|
'staticValues' => [
|
||||||
|
'serverName' => $serverName,
|
||||||
|
'serverCnt' => $serverCnt,
|
||||||
|
'serverNick' => DB::prefix(),
|
||||||
|
'serverID' => UniqueConst::$serverID,
|
||||||
|
'maxTurn' => GameConst::$maxTurn,
|
||||||
|
'maxPushTurn' => 12,
|
||||||
|
'commandList' => getCommandTable($generalObj),
|
||||||
|
'serverNow' => TimeUtil::now(false),
|
||||||
|
'lastExecuted' => $gameStor->turntime,
|
||||||
|
'isLocked' => $plock,
|
||||||
|
'isTournamentActive' => $isTournamentActive,
|
||||||
|
'isBettingActive' => $isBettingActive,
|
||||||
|
'mapName' => GameConst::$mapName,
|
||||||
|
'unitSet' => GameConst::$unitSet,
|
||||||
|
]
|
||||||
]) ?>
|
]) ?>
|
||||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
|
||||||
</head>
|
</head>
|
||||||
@@ -241,7 +256,7 @@ if (!$otherTextInfo) {
|
|||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<div id="map_view" class="gx-0">
|
<div id="map_view" class="gx-0">
|
||||||
<div id="mapZone" class="view-item"><?= getMapHtml($mapTheme) ?></div>
|
<div id="mapZone" class="view-item"><?= getMapHtml() ?></div>
|
||||||
<div class="view-item" id="reservedCommandZone">
|
<div class="view-item" id="reservedCommandZone">
|
||||||
<div id="reservedCommandList"></div>
|
<div id="reservedCommandList"></div>
|
||||||
<div id="actionMiniPlate" class="gx-0 row">
|
<div id="actionMiniPlate" class="gx-0 row">
|
||||||
@@ -257,7 +272,7 @@ if (!$otherTextInfo) {
|
|||||||
<div id="nation-position"><?php myNationInfo($generalObj); ?></div>
|
<div id="nation-position"><?php myNationInfo($generalObj); ?></div>
|
||||||
<div id="general-position"><?php generalInfo($generalObj); ?></div>
|
<div id="general-position"><?php generalInfo($generalObj); ?></div>
|
||||||
<div id="generalCommandButton" class="row gx-0">
|
<div id="generalCommandButton" class="row gx-0">
|
||||||
<div class="buttonPlate bg2"><?= commandButton(['btnClass' => 'btn btn-sammo-nation', 'isTournamentActive' => $isTournamentActive, 'isBettingActive' => $isBettingActive]) ?></div>
|
<div class="buttonPlate bg2"><?= commandButton(['btnClass' => 'btn btn-sammo-nation', 'isTournamentApplicationOpen' => $isTournamentApplicationOpen, 'isBettingActive' => $isBettingActive]) ?></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -357,7 +372,7 @@ if (!$otherTextInfo) {
|
|||||||
국가 메뉴
|
국가 메뉴
|
||||||
</div>
|
</div>
|
||||||
<ul class="dropdown-menu" aria-labelledby="navbarNation" id="navbarNationItems">
|
<ul class="dropdown-menu" aria-labelledby="navbarNation" id="navbarNationItems">
|
||||||
<?= commandButton(['btnBegin' => '<li>', 'btnEnd' => '</li>', 'btnClass' => 'dropdown-item', 'isTournamentActive' => $isTournamentActive, 'isBettingActive' => $isBettingActive]) ?>
|
<?= commandButton(['btnBegin' => '<li>', 'btnEnd' => '</li>', 'btnClass' => 'dropdown-item', 'isTournamentApplicationOpen' => $isTournamentApplicationOpen, 'isBettingActive' => $isBettingActive]) ?>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropup">
|
<li class="nav-item dropup">
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ if ($permission < 4) {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$reason = trim($reason);
|
|
||||||
|
|
||||||
$letter = $db->queryFirstRow('SELECT * FROM ng_diplomacy WHERE no=%i AND src_nation_id = %i AND state = \'proposed\'', $letterNo, $me['nation']);
|
$letter = $db->queryFirstRow('SELECT * FROM ng_diplomacy WHERE no=%i AND src_nation_id = %i AND state = \'proposed\'', $letterNo, $me['nation']);
|
||||||
if(!$letter){
|
if(!$letter){
|
||||||
Json::die([
|
Json::die([
|
||||||
@@ -66,7 +64,7 @@ $unlimited = new \DateTime('9999-12-31');
|
|||||||
$aux['reason'] = [
|
$aux['reason'] = [
|
||||||
'who'=>$me['no'],
|
'who'=>$me['no'],
|
||||||
'action'=>'cancelled',
|
'action'=>'cancelled',
|
||||||
'reason'=>$reason
|
'reason'=>'회수',
|
||||||
];
|
];
|
||||||
$db->update('ng_diplomacy', [
|
$db->update('ng_diplomacy', [
|
||||||
'state'=>'cancelled',
|
'state'=>'cancelled',
|
||||||
|
|||||||
@@ -1,109 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace sammo;
|
|
||||||
|
|
||||||
include "lib.php";
|
|
||||||
include "func.php";
|
|
||||||
|
|
||||||
|
|
||||||
//로그인 검사
|
|
||||||
$session = Session::requireLogin([]);
|
|
||||||
$userID = Session::getUserID();
|
|
||||||
|
|
||||||
$db = DB::db();
|
|
||||||
$withToken = Util::getPost('with_token', 'bool', false);
|
|
||||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
|
||||||
|
|
||||||
if($session->isGameLoggedIn()){
|
|
||||||
increaseRefresh("장수일람", 2);
|
|
||||||
|
|
||||||
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner=%i', $userID);
|
|
||||||
$con = checkLimit($me['con']);
|
|
||||||
if ($con >= 2) {
|
|
||||||
Json::die([
|
|
||||||
'result'=>false,
|
|
||||||
'reason'=>'접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$availableNextCall = $session->availableNextCallGetGeneralList??'2000-01-01 00:00:00';
|
|
||||||
$now = new \DateTimeImmutable();
|
|
||||||
|
|
||||||
if($now <= new \DateTimeImmutable($availableNextCall) && $session->userGrade < 5){
|
|
||||||
Json::die([
|
|
||||||
'result'=>false,
|
|
||||||
'reason'=>"장수 리스트는 10초에 한번 갱신 가능합니다.\n다음 시간 : ".$availableNextCall
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$availableNextCall = $now->add(new \DateInterval('PT10S'))->format('Y-m-d H:i:s');
|
|
||||||
$session->availableNextCallGetGeneralList = $availableNextCall;
|
|
||||||
}
|
|
||||||
|
|
||||||
$session->setReadOnly();
|
|
||||||
|
|
||||||
$rawGeneralList = $db->queryAllLists('SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,owner_name as ownerName,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,connect from general');
|
|
||||||
|
|
||||||
$ownerNameList = [];
|
|
||||||
if($gameStor->isunited){
|
|
||||||
foreach(RootDB::db()->queryAllLists('SELECT no, name FROM member') as [$ownerID, $ownerName]){
|
|
||||||
$ownerNameList[$ownerID] = $ownerName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$generalList = [];
|
|
||||||
foreach($rawGeneralList as $rawGeneral){
|
|
||||||
[$owner,$no,$picture,$imgsvr,$npc,$age,$nation,$special,$special2,$personal,$name,$ownerName,$injury,$leadership,$strength,$intel,$experience,$dedication,$officerLevel,$killturn,$connectCnt] = $rawGeneral;
|
|
||||||
|
|
||||||
if(key_exists($owner, $ownerNameList)){
|
|
||||||
$ownerName = $ownerNameList[$owner];
|
|
||||||
}
|
|
||||||
|
|
||||||
$nationArr = getNationStaticInfo($nation);
|
|
||||||
$lbonus = calcLeadershipBonus($officerLevel, $nationArr['level']);
|
|
||||||
|
|
||||||
$generalList[] = [
|
|
||||||
$no,
|
|
||||||
$picture,
|
|
||||||
$imgsvr,
|
|
||||||
$npc,
|
|
||||||
$age,
|
|
||||||
$nationArr['name'],
|
|
||||||
getGeneralSpecialDomesticName($special),
|
|
||||||
getGeneralSpecialWarName($special2),
|
|
||||||
getGenChar($personal),
|
|
||||||
$name,
|
|
||||||
$npc==1?$ownerName:null,
|
|
||||||
$injury,
|
|
||||||
$leadership,
|
|
||||||
$lbonus,
|
|
||||||
$strength,
|
|
||||||
$intel,
|
|
||||||
getExpLevel($experience),
|
|
||||||
getHonor($experience),
|
|
||||||
getDed($dedication),
|
|
||||||
getOfficerLevelText($officerLevel, $nationArr['level']),
|
|
||||||
$killturn,
|
|
||||||
$connectCnt
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = [
|
|
||||||
'result'=>'true',
|
|
||||||
'list'=>$generalList,
|
|
||||||
];
|
|
||||||
|
|
||||||
if($withToken){
|
|
||||||
$now = (new \DateTimeImmutable())->format('Y-m-d H:i:s');
|
|
||||||
$tokens = [];
|
|
||||||
foreach($db->query('SELECT * FROM select_npc_token WHERE `valid_until`>=%s', $now) as $token){
|
|
||||||
$validUntil = $token['valid_until'];
|
|
||||||
|
|
||||||
foreach(Json::decode($token['pick_result']) as $pickResult){
|
|
||||||
$tokens[$pickResult['no']]=$pickResult['keepCnt'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$result['token'] = $tokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::die($result);
|
|
||||||
@@ -1,184 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace sammo;
|
|
||||||
|
|
||||||
//통합 세력장수&암행부 viewer
|
|
||||||
|
|
||||||
include "lib.php";
|
|
||||||
include "func.php";
|
|
||||||
|
|
||||||
//로그인 검사
|
|
||||||
$session = Session::requireGameLogin([])->setReadOnly();
|
|
||||||
$userID = Session::getUserID();
|
|
||||||
|
|
||||||
$db = DB::db();
|
|
||||||
$reqType = Util::getReq('req', 'int', 1);
|
|
||||||
$reqForce = Util::getReq('force', 'bool', false);
|
|
||||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
|
||||||
|
|
||||||
increaseRefresh("세력장수", 1);
|
|
||||||
|
|
||||||
$me = $db->queryFirstRow('SELECT con, turntime, belong, nation, officer_level, permission, penalty FROM general WHERE owner=%i', $userID);
|
|
||||||
$con = checkLimit($me['con']);
|
|
||||||
if ($con >= 2) {
|
|
||||||
Json::die([
|
|
||||||
'result' => false,
|
|
||||||
'reason' => '접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$nationID = $me['nation'];
|
|
||||||
$permission = checkSecretPermission($me, true);
|
|
||||||
if ($reqForce && $reqType > $permission) {
|
|
||||||
Json::die([
|
|
||||||
'result' => false,
|
|
||||||
'reason' => '권한이 부족합니다.'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
$permission = min($reqType, $permission);
|
|
||||||
$nationArr = getNationStaticInfo($nationID);
|
|
||||||
$viewColumns = [
|
|
||||||
'no' => 0,
|
|
||||||
'name' => 0,
|
|
||||||
'owner_name' => 9,
|
|
||||||
'nation' => 0,
|
|
||||||
'city' => 1,
|
|
||||||
'officer_level' => 2,
|
|
||||||
'officer_city' => 2,
|
|
||||||
'npc' => 0,
|
|
||||||
'defence_train' => 2,
|
|
||||||
'troop' => 2,
|
|
||||||
'injury' => 0,
|
|
||||||
'leadership' => 0,
|
|
||||||
'strength' => 0,
|
|
||||||
'intel' => 0,
|
|
||||||
'experience' => 1,
|
|
||||||
'explevel' => 0,
|
|
||||||
'dedication' => 1,
|
|
||||||
'dedlevel' => 0,
|
|
||||||
'gold' => 0,
|
|
||||||
'rice' => 0,
|
|
||||||
'crewtype' => 2,
|
|
||||||
'crew' => 2,
|
|
||||||
'train' => 2,
|
|
||||||
'atmos' => 2,
|
|
||||||
'killturn' => 0,
|
|
||||||
'turntime' => 2,
|
|
||||||
'picture' => 0,
|
|
||||||
'imgsvr' => 0,
|
|
||||||
'age' => 0,
|
|
||||||
'special' => 0,
|
|
||||||
'special2' => 0,
|
|
||||||
'personal' => 0,
|
|
||||||
'belong' => 0,
|
|
||||||
'horse' => 2,
|
|
||||||
'weapon' => 2,
|
|
||||||
'book' => 2,
|
|
||||||
'item' => 2,
|
|
||||||
'connect' => 0
|
|
||||||
];
|
|
||||||
|
|
||||||
$customViewColumns = [
|
|
||||||
'officerLevel' => 0,
|
|
||||||
'officerLevelText' => 0,
|
|
||||||
'lbonus' => 0,
|
|
||||||
'ownerName' => 0,
|
|
||||||
'honorText' => 0
|
|
||||||
];
|
|
||||||
|
|
||||||
function getOfficerLevel($rawGeneral)
|
|
||||||
{
|
|
||||||
global $permission;
|
|
||||||
$level = $rawGeneral['officer_level'];
|
|
||||||
if ($level >= 5) {
|
|
||||||
return $level;
|
|
||||||
}
|
|
||||||
if ($permission > 1) {
|
|
||||||
return $level;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$specialViewFilter = [
|
|
||||||
'officerLevel' => function ($rawGeneral){
|
|
||||||
return getOfficerLevel($rawGeneral);
|
|
||||||
},
|
|
||||||
'special' => function ($rawGeneral) {
|
|
||||||
return getGeneralSpecialDomesticName($rawGeneral['special']);
|
|
||||||
},
|
|
||||||
'special2' => function ($rawGeneral) {
|
|
||||||
return getGeneralSpecialWarName($rawGeneral['special2']);
|
|
||||||
},
|
|
||||||
'personal' => function ($rawGeneral) {
|
|
||||||
return getGenChar($rawGeneral['personal']);
|
|
||||||
},
|
|
||||||
'lbonus' => function ($rawGeneral) use ($nationArr) {
|
|
||||||
return calcLeadershipBonus($rawGeneral['officer_level'], $nationArr['level']);
|
|
||||||
},
|
|
||||||
'ownerName' => function ($rawGeneral) {
|
|
||||||
if ($rawGeneral['npc'] != 1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $rawGeneral['owner_name'];
|
|
||||||
},
|
|
||||||
'officerLevelText' => function ($rawGeneral) use ($nationArr) {
|
|
||||||
$level = getOfficerLevel($rawGeneral);
|
|
||||||
return getOfficerLevelText($level, $nationArr['level']);
|
|
||||||
},
|
|
||||||
'honorText' => function ($rawGeneral) {
|
|
||||||
return getHonor($rawGeneral['experience']);
|
|
||||||
},
|
|
||||||
'dedLevelText' => function ($rawGeneral) {
|
|
||||||
return getDedLevelText($rawGeneral['dedLevel']);
|
|
||||||
},
|
|
||||||
'turntime' => function ($rawGeneral) {
|
|
||||||
//'0000-00-00 11:23';
|
|
||||||
return substr($rawGeneral['turntime'], 11, 5);
|
|
||||||
}
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
[$queryColumns, $rankColumns] = General::mergeQueryColumn(array_keys($viewColumns), 1);
|
|
||||||
|
|
||||||
$rawGeneralList = Util::convertArrayToDict($db->query('SELECT %l from general WHERE nation = %i', Util::formatListOfBackticks($queryColumns), $nationID), 'no');
|
|
||||||
|
|
||||||
$resultColumns = [];
|
|
||||||
foreach ($viewColumns as $column => $reqPermission) {
|
|
||||||
if ($reqPermission > $permission) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$resultColumns[] = $column;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($customViewColumns as $column => $reqPermission) {
|
|
||||||
if ($reqPermission > $permission) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$resultColumns[] = $column;
|
|
||||||
}
|
|
||||||
|
|
||||||
$generalList = [];
|
|
||||||
foreach ($rawGeneralList as $rawGeneral) {
|
|
||||||
//General 생성?
|
|
||||||
|
|
||||||
$item = [];
|
|
||||||
foreach ($resultColumns as $column) {
|
|
||||||
if (key_exists($column, $specialViewFilter)) {
|
|
||||||
$value = $specialViewFilter[$column]($rawGeneral);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
$value = $rawGeneral[$column];
|
|
||||||
}
|
|
||||||
$item[] = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
$generalList[] = $item;
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = [
|
|
||||||
'result' => true,
|
|
||||||
'column' => $resultColumns,
|
|
||||||
'list' => $generalList,
|
|
||||||
];
|
|
||||||
|
|
||||||
Json::die($result);
|
|
||||||
+8
-15
@@ -31,17 +31,12 @@ $now = time();
|
|||||||
if($mapInfo && ($now - $mapInfo['timestamp'] < 600)){
|
if($mapInfo && ($now - $mapInfo['timestamp'] < 600)){
|
||||||
$mapEtag = $mapInfo['etag'];
|
$mapEtag = $mapInfo['etag'];
|
||||||
$mapModified = $mapInfo['timestamp'];
|
$mapModified = $mapInfo['timestamp'];
|
||||||
|
WebUtil::setCacheHeader(new APICacheResult(TimeUtil::secondsToDateTime($mapModified), $mapEtag));
|
||||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $mapModified)." GMT");
|
$reqMapEtag = WebUtil::parseETag();
|
||||||
header("Etag: $mapEtag");
|
$reqModifiedSince = WebUtil::parseLastModified();
|
||||||
|
if($mapEtag === $reqMapEtag || $mapModified === $reqModifiedSince){
|
||||||
if (
|
WebUtil::dieWithNotModified();
|
||||||
strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']??'2000-01-01') === $mapModified ||
|
}
|
||||||
trim($_SERVER['HTTP_IF_NONE_MATCH']??'') === $mapEtag
|
|
||||||
) {
|
|
||||||
header("HTTP/1.1 304 Not Modified");
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::die($mapInfo['data'], 0);
|
Json::die($mapInfo['data'], 0);
|
||||||
}
|
}
|
||||||
@@ -65,10 +60,9 @@ $rawMap = getWorldMap([
|
|||||||
|
|
||||||
$db = DB::db();
|
$db = DB::db();
|
||||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||||
$mapTheme = $gameStor->map_theme ?? 'che';
|
|
||||||
|
|
||||||
$rawMap['history'] = $history;
|
$rawMap['history'] = $history;
|
||||||
$rawMap['theme'] = $mapTheme;
|
$rawMap['theme'] = GameConst::$mapName;
|
||||||
|
|
||||||
$etag = hash('sha256', $serverID.$now);
|
$etag = hash('sha256', $serverID.$now);
|
||||||
$map = [
|
$map = [
|
||||||
@@ -77,7 +71,6 @@ $map = [
|
|||||||
'data'=>$rawMap,
|
'data'=>$rawMap,
|
||||||
];
|
];
|
||||||
$cache->save("recent_map", $map);
|
$cache->save("recent_map", $map);
|
||||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $now)." GMT");
|
WebUtil::setCacheHeader(new APICacheResult(TimeUtil::secondsToDateTime($now), $etag));
|
||||||
header("Etag: $etag");
|
|
||||||
|
|
||||||
Json::die($map['data'], 0);
|
Json::die($map['data'], 0);
|
||||||
+21
-8
@@ -231,7 +231,10 @@ function processWar_NG(
|
|||||||
$logger->pushGlobalActionLog("<D><b>{$attacker->getNationVar('name')}</b></>의 <Y>{$attacker->getName()}</>{$josaYi} <G><b>{$city->getName()}</b></>{$josaRo} 진격합니다.");
|
$logger->pushGlobalActionLog("<D><b>{$attacker->getNationVar('name')}</b></>의 <Y>{$attacker->getName()}</>{$josaYi} <G><b>{$city->getName()}</b></>{$josaRo} 진격합니다.");
|
||||||
$logger->pushGeneralActionLog("<G><b>{$city->getName()}</b></>{$josaRo} <M>진격</>합니다. <1>$date</>");
|
$logger->pushGeneralActionLog("<G><b>{$city->getName()}</b></>{$josaRo} <M>진격</>합니다. <1>$date</>");
|
||||||
|
|
||||||
for ($currPhase = 0; $currPhase < $attacker->getMaxPhase(); $currPhase += 1) {
|
$logWritten = false;
|
||||||
|
|
||||||
|
while($attacker->getPhase() < $attacker->getMaxPhase()){
|
||||||
|
$logWritten = false;
|
||||||
if ($defender === null) {
|
if ($defender === null) {
|
||||||
$defender = $city;
|
$defender = $city;
|
||||||
|
|
||||||
@@ -256,8 +259,8 @@ function processWar_NG(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($defender->getPhase() == 0) {
|
if ($defender->getPhase() == 0 && $defender->getOppose() == null) {
|
||||||
$defender->setPrePhase($currPhase);
|
$defender->setPrePhase($attacker->getPhase());
|
||||||
|
|
||||||
$attacker->addTrain(1);
|
$attacker->addTrain(1);
|
||||||
$defender->addTrain(1);
|
$defender->addTrain(1);
|
||||||
@@ -347,15 +350,22 @@ function processWar_NG(
|
|||||||
$attacker->increaseKilled($deadDefender);
|
$attacker->increaseKilled($deadDefender);
|
||||||
$defender->increaseKilled($deadAttacker);
|
$defender->increaseKilled($deadAttacker);
|
||||||
|
|
||||||
$phaseNickname = $currPhase + 1;
|
if($defender->getPhase() < 0){
|
||||||
|
$phaseNickname = '先';
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$currPhase = $attacker->getPhase() + 1;
|
||||||
|
$phaseNickname = "{$currPhase} ";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($deadAttacker > 0 || $deadDefender > 0) {
|
if ($deadAttacker > 0 || $deadDefender > 0) {
|
||||||
$attacker->getLogger()->pushGeneralBattleDetailLog(
|
$attacker->getLogger()->pushGeneralBattleDetailLog(
|
||||||
"$phaseNickname : <Y1>【{$attacker->getName()}】</> <C>{$attacker->getHP()} (-$deadAttacker)</> VS <C>{$defender->getHP()} (-$deadDefender)</> <Y1>【{$defender->getName()}】</>"
|
"$phaseNickname: <Y1>【{$attacker->getName()}】</> <C>{$attacker->getHP()} (-$deadAttacker)</> VS <C>{$defender->getHP()} (-$deadDefender)</> <Y1>【{$defender->getName()}】</>"
|
||||||
);
|
);
|
||||||
|
|
||||||
$defender->getLogger()->pushGeneralBattleDetailLog(
|
$defender->getLogger()->pushGeneralBattleDetailLog(
|
||||||
"$phaseNickname : <Y1>【{$defender->getName()}】</> <C>{$defender->getHP()} (-$deadDefender)</> VS <C>{$attacker->getHP()} (-$deadAttacker)</> <Y1>【{$attacker->getName()}】</>"
|
"$phaseNickname: <Y1>【{$defender->getName()}】</> <C>{$defender->getHP()} (-$deadDefender)</> VS <C>{$attacker->getHP()} (-$deadAttacker)</> <Y1>【{$attacker->getName()}】</>"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,6 +374,8 @@ function processWar_NG(
|
|||||||
$defender->addPhase();
|
$defender->addPhase();
|
||||||
|
|
||||||
if (!$attacker->continueWar($noRice)) {
|
if (!$attacker->continueWar($noRice)) {
|
||||||
|
$logWritten = true;
|
||||||
|
|
||||||
$attacker->logBattleResult();
|
$attacker->logBattleResult();
|
||||||
$defender->logBattleResult();
|
$defender->logBattleResult();
|
||||||
|
|
||||||
@@ -386,6 +398,7 @@ function processWar_NG(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$defender->continueWar($noRice)) {
|
if (!$defender->continueWar($noRice)) {
|
||||||
|
$logWritten = true;
|
||||||
|
|
||||||
$attacker->logBattleResult();
|
$attacker->logBattleResult();
|
||||||
$defender->logBattleResult();
|
$defender->logBattleResult();
|
||||||
@@ -414,7 +427,7 @@ function processWar_NG(
|
|||||||
$defender->getLogger()->pushGeneralActionLog("전멸했습니다.", ActionLogger::PLAIN);
|
$defender->getLogger()->pushGeneralActionLog("전멸했습니다.", ActionLogger::PLAIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($currPhase + 1 == $attacker->getMaxPhase()) {
|
if ($attacker->getPhase() >= $attacker->getMaxPhase()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,7 +440,7 @@ function processWar_NG(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($currPhase == $attacker->getMaxPhase()) {
|
if (!$logWritten) {
|
||||||
//마지막 페이즈의 전투 마무리
|
//마지막 페이즈의 전투 마무리
|
||||||
$attacker->logBattleResult();
|
$attacker->logBattleResult();
|
||||||
$defender->logBattleResult();
|
$defender->logBattleResult();
|
||||||
|
|||||||
+4
-2
@@ -16,8 +16,10 @@ include "func.php";
|
|||||||
<title>최근 지도</title>
|
<title>최근 지도</title>
|
||||||
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
|
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
|
||||||
<?= WebUtil::printStaticValues([
|
<?= WebUtil::printStaticValues([
|
||||||
'serverNick' => DB::prefix(),
|
'staticValues' => [
|
||||||
'serverID' => UniqueConst::$serverID
|
'serverNick' => DB::prefix(),
|
||||||
|
'serverID' => UniqueConst::$serverID
|
||||||
|
],
|
||||||
]) ?>
|
]) ?>
|
||||||
<?= WebUtil::printJS('d_shared/base_map.js') ?>
|
<?= WebUtil::printJS('d_shared/base_map.js') ?>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\API\Command;
|
||||||
|
|
||||||
|
use sammo\Session;
|
||||||
|
use DateTimeInterface;
|
||||||
|
use sammo\GameConst;
|
||||||
|
use sammo\Util;
|
||||||
|
use sammo\Validator;
|
||||||
|
|
||||||
|
use function sammo\setGeneralCommand;
|
||||||
|
|
||||||
|
class ReserveBulkCommand extends \sammo\BaseAPI
|
||||||
|
{
|
||||||
|
public function validateArgs(): ?string
|
||||||
|
{
|
||||||
|
foreach ($this->args as $idx => $turn) {
|
||||||
|
$v = new Validator($turn);
|
||||||
|
$v->rule('required', [
|
||||||
|
'action',
|
||||||
|
'turnList'
|
||||||
|
])
|
||||||
|
->rule('lengthMin', 'action', 1)
|
||||||
|
->rule('integerArray', 'turnList');
|
||||||
|
|
||||||
|
if (!$v->validate()) {
|
||||||
|
return "{$idx}:{$v->errorStr()}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequiredSessionMode(): int
|
||||||
|
{
|
||||||
|
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||||
|
{
|
||||||
|
$briefList = [];
|
||||||
|
foreach ($this->args as $idx => $turn) {
|
||||||
|
$action = $turn['action'];
|
||||||
|
$turnList = $turn['turnList'];
|
||||||
|
$arg = $turn['arg'] ?? [];
|
||||||
|
|
||||||
|
if (!$turnList) {
|
||||||
|
return "{$idx}: 턴이 입력되지 않았습니다";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($action, Util::array_flatten(GameConst::$availableGeneralCommand))) {
|
||||||
|
return "{$idx}: 사용할 수 없는 커맨드입니다.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($arg)) {
|
||||||
|
return "{$idx}: 올바른 arg 형태가 아닙니다.";
|
||||||
|
}
|
||||||
|
$partialResult = setGeneralCommand($session->generalID, $turnList, $action, $arg);
|
||||||
|
if(!$partialResult['result']){
|
||||||
|
return [
|
||||||
|
'result' => false,
|
||||||
|
'briefList' => $briefList,
|
||||||
|
'errorIdx' => $idx,
|
||||||
|
'reason' => $partialResult['reason']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$briefList[$idx] = $partialResult['brief'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'result' => true,
|
||||||
|
'briefList' => $briefList,
|
||||||
|
'reason' => 'success'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\API\List\Nation;
|
||||||
|
|
||||||
|
use sammo\DB;
|
||||||
|
use sammo\General;
|
||||||
|
use sammo\Json;
|
||||||
|
use sammo\KVStorage;
|
||||||
|
use sammo\RootDB;
|
||||||
|
use sammo\Session;
|
||||||
|
use sammo\Util;
|
||||||
|
use sammo\Validator;
|
||||||
|
|
||||||
|
use function sammo\calcLeadershipBonus;
|
||||||
|
use function sammo\checkLimit;
|
||||||
|
use function sammo\checkSecretPermission;
|
||||||
|
use function sammo\getDed;
|
||||||
|
use function sammo\getDedLevelText;
|
||||||
|
use function sammo\getExpLevel;
|
||||||
|
use function sammo\getGenChar;
|
||||||
|
use function sammo\getGeneralSpecialDomesticName;
|
||||||
|
use function sammo\getGeneralSpecialWarName;
|
||||||
|
use function sammo\getHonor;
|
||||||
|
use function sammo\getNationStaticInfo;
|
||||||
|
use function sammo\getOfficerLevelText;
|
||||||
|
use function sammo\increaseRefresh;
|
||||||
|
|
||||||
|
class GeneralList extends \sammo\BaseAPI
|
||||||
|
{
|
||||||
|
public function validateArgs(): ?string
|
||||||
|
{
|
||||||
|
$v = new Validator($this->args);
|
||||||
|
$v
|
||||||
|
->rule('boolean', 'with_token');
|
||||||
|
if (!$v->validate()) {
|
||||||
|
return $v->errorStr();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequiredSessionMode(): int
|
||||||
|
{
|
||||||
|
return static::REQ_LOGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch(Session $session, ?\DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||||
|
{
|
||||||
|
$db = DB::db();
|
||||||
|
$withToken = $this->args['with_token']??false;
|
||||||
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||||
|
|
||||||
|
$userID = $session->userID;
|
||||||
|
if ($session->isGameLoggedIn()) {
|
||||||
|
increaseRefresh("장수일람", 2);
|
||||||
|
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner=%i', $userID);
|
||||||
|
$con = checkLimit($me['con']);
|
||||||
|
if ($con >= 2) {
|
||||||
|
return '접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$availableNextCall = $session->availableNextCallGetGeneralList ?? '2000-01-01 00:00:00';
|
||||||
|
$now = new \DateTimeImmutable();
|
||||||
|
|
||||||
|
if ($now <= new \DateTimeImmutable($availableNextCall) && $session->userGrade < 5) {
|
||||||
|
return "장수 리스트는 10초에 한번 갱신 가능합니다.\n다음 시간 : " . $availableNextCall;
|
||||||
|
}
|
||||||
|
|
||||||
|
$availableNextCall = $now->add(new \DateInterval('PT10S'))->format('Y-m-d H:i:s');
|
||||||
|
$session->availableNextCallGetGeneralList = $availableNextCall;
|
||||||
|
}
|
||||||
|
|
||||||
|
$session->setReadOnly();
|
||||||
|
|
||||||
|
|
||||||
|
$rawGeneralList = $db->queryAllLists('SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,owner_name as ownerName,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,connect from general');
|
||||||
|
|
||||||
|
$ownerNameList = [];
|
||||||
|
if ($gameStor->isunited) {
|
||||||
|
foreach (RootDB::db()->queryAllLists('SELECT no, name FROM member') as [$ownerID, $ownerName]) {
|
||||||
|
$ownerNameList[$ownerID] = $ownerName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$generalList = [];
|
||||||
|
foreach ($rawGeneralList as $rawGeneral) {
|
||||||
|
[$owner, $no, $picture, $imgsvr, $npc, $age, $nation, $special, $special2, $personal, $name, $ownerName, $injury, $leadership, $strength, $intel, $experience, $dedication, $officerLevel, $killturn, $connectCnt] = $rawGeneral;
|
||||||
|
|
||||||
|
if (key_exists($owner, $ownerNameList)) {
|
||||||
|
$ownerName = $ownerNameList[$owner];
|
||||||
|
}
|
||||||
|
|
||||||
|
$nationArr = getNationStaticInfo($nation);
|
||||||
|
$lbonus = calcLeadershipBonus($officerLevel, $nationArr['level']);
|
||||||
|
|
||||||
|
$generalList[] = [
|
||||||
|
$no,
|
||||||
|
$picture,
|
||||||
|
$imgsvr,
|
||||||
|
$npc,
|
||||||
|
$age,
|
||||||
|
$nationArr['name'],
|
||||||
|
getGeneralSpecialDomesticName($special),
|
||||||
|
getGeneralSpecialWarName($special2),
|
||||||
|
getGenChar($personal),
|
||||||
|
$name,
|
||||||
|
$npc == 1 ? $ownerName : null,
|
||||||
|
$injury,
|
||||||
|
$leadership,
|
||||||
|
$lbonus,
|
||||||
|
$strength,
|
||||||
|
$intel,
|
||||||
|
getExpLevel($experience),
|
||||||
|
getHonor($experience),
|
||||||
|
getDed($dedication),
|
||||||
|
getOfficerLevelText($officerLevel, $nationArr['level']),
|
||||||
|
$killturn,
|
||||||
|
$connectCnt
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$resultColumns = [
|
||||||
|
'no',
|
||||||
|
'picture',
|
||||||
|
'imgsvr',
|
||||||
|
'npc',
|
||||||
|
'age',
|
||||||
|
'nationName',
|
||||||
|
'special',
|
||||||
|
'special2',
|
||||||
|
'personal',
|
||||||
|
'name',
|
||||||
|
'ownerName',
|
||||||
|
'injury',
|
||||||
|
'leadership',
|
||||||
|
'lbonus',
|
||||||
|
'strength',
|
||||||
|
'intel',
|
||||||
|
'explevel',
|
||||||
|
'honorText',
|
||||||
|
'dedLevelText',
|
||||||
|
'officerLevelText',
|
||||||
|
];
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
'result' => 'true',
|
||||||
|
'column' => $resultColumns,
|
||||||
|
'list' => $generalList,
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
if ($withToken) {
|
||||||
|
$now = (new \DateTimeImmutable())->format('Y-m-d H:i:s');
|
||||||
|
$tokens = [];
|
||||||
|
foreach ($db->query('SELECT * FROM select_npc_token WHERE `valid_until`>=%s', $now) as $token) {
|
||||||
|
$validUntil = $token['valid_until'];
|
||||||
|
|
||||||
|
foreach (Json::decode($token['pick_result']) as $pickResult) {
|
||||||
|
$tokens[$pickResult['no']] = $pickResult['keepCnt'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$result['token'] = $tokens;
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,325 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\API\Global;
|
||||||
|
|
||||||
|
use sammo\Session;
|
||||||
|
use DateTimeInterface;
|
||||||
|
use sammo\VersionGit;
|
||||||
|
use Nette\Caching\Cache;
|
||||||
|
use RuntimeException;
|
||||||
|
use sammo\APICacheResult;
|
||||||
|
use sammo\CityConst;
|
||||||
|
use sammo\GameConst;
|
||||||
|
use sammo\GameUnitConst;
|
||||||
|
use sammo\Json;
|
||||||
|
use sammo\TimeUtil;
|
||||||
|
use sammo\UniqueConst;
|
||||||
|
|
||||||
|
use function sammo\prepareDir;
|
||||||
|
|
||||||
|
class GetConst extends \sammo\BaseAPI
|
||||||
|
{
|
||||||
|
/** 반환하는 StaticValues 타입이 달라지면 +1 */
|
||||||
|
const CONST_API_VERSION = 2;
|
||||||
|
const CACHE_KEY = 'JSConst';
|
||||||
|
|
||||||
|
private ?string $cacheKey = null;
|
||||||
|
|
||||||
|
public function __construct(string $rootPath, array $args)
|
||||||
|
{
|
||||||
|
parent::__construct($rootPath, $args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validateArgs(): ?string
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequiredSessionMode(): int
|
||||||
|
{
|
||||||
|
return static::REQ_LOGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findLastModified(): ?int
|
||||||
|
{
|
||||||
|
$rawResult = explode("\n", shell_exec('git status -u -s --no-rename'));
|
||||||
|
$files = [];
|
||||||
|
foreach ($rawResult as $rawLine) {
|
||||||
|
if (strlen($rawLine) < 3) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$filePath = trim(substr($rawLine, 3));
|
||||||
|
if ($filePath[0] == '"') {
|
||||||
|
$filePath = substr($filePath, 1, strlen($filePath) - 2);
|
||||||
|
}
|
||||||
|
if (!file_exists($filePath)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$files[] = $filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
$lastModified = null;
|
||||||
|
foreach ($files as $filePath) {
|
||||||
|
$fileModified = filemtime($filePath);
|
||||||
|
if ($fileModified === false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($lastModified === null) {
|
||||||
|
$lastModified = $fileModified;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($lastModified > $fileModified) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$lastModified = $fileModified;
|
||||||
|
}
|
||||||
|
if ($lastModified === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return $lastModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCacheKey(): string
|
||||||
|
{
|
||||||
|
if ($this->cacheKey !== null) {
|
||||||
|
return $this->cacheKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_subclass_of('\\sammo\\VersionGit', '\\sammo\VersionGitDynamic')) {
|
||||||
|
$lastModified = $this->findLastModified();
|
||||||
|
if ($lastModified !== null) {
|
||||||
|
$versionHash = "lt{$lastModified}";
|
||||||
|
} else {
|
||||||
|
$versionHash = VersionGit::getHash();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$versionHash = VersionGit::getHash();
|
||||||
|
}
|
||||||
|
|
||||||
|
$apiVersion = static::CONST_API_VERSION;
|
||||||
|
$serverID = UniqueConst::$serverID;
|
||||||
|
|
||||||
|
|
||||||
|
$cacheKey = "{$apiVersion}_{$serverID}_{$versionHash}";
|
||||||
|
$this->cacheKey = $cacheKey;
|
||||||
|
|
||||||
|
return $cacheKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tryCache(): ?APICacheResult
|
||||||
|
{
|
||||||
|
if (is_subclass_of('\\sammo\\VersionGit', '\\sammo\VersionGitDynamic')) {
|
||||||
|
return new APICacheResult(TimeUtil::secondsToDateTime($this->findLastModified()??\time(), true, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new APICacheResult(null, $this->getCacheKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function readCache(Cache $cache): null|string|array|int|float|bool
|
||||||
|
{
|
||||||
|
$rawJSONCache = $cache->load(static::CACHE_KEY);
|
||||||
|
if ($rawJSONCache === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
$jsonCache = Json::decode($rawJSONCache);
|
||||||
|
if (!key_exists('cacheKey', $jsonCache)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$jsonCacheKey = $jsonCache['cacheKey'];
|
||||||
|
if ($jsonCacheKey !== $this->getCacheKey()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $jsonCache['data'] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function extractObjClassInfo(string $objKey, callable $callerFunction): array
|
||||||
|
{
|
||||||
|
/** @var \sammo\iAction */
|
||||||
|
$target = $callerFunction($objKey);
|
||||||
|
if (!($target instanceof \sammo\iAction)) {
|
||||||
|
throw new \RuntimeException("{$objKey}의 대상이 iAction이 아님");
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
'value' => $objKey,
|
||||||
|
'name' => $target->getName(),
|
||||||
|
'info' => $target->getInfo(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function extractObjClassInfoFromArray(array $constArray, callable $callerFunction): array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
foreach ($constArray as $key => $target) {
|
||||||
|
if (is_string($target)) {
|
||||||
|
$actionInfo = $this->extractObjClassInfo($target, $callerFunction);
|
||||||
|
if (is_string($key)) {
|
||||||
|
$result[$key] = $actionInfo;
|
||||||
|
} else {
|
||||||
|
$result[$target] = $actionInfo;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (is_array($target)) {
|
||||||
|
$result[$key] = $this->extractObjClassInfoFromArray($target, $callerFunction);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(is_string($key) && is_int($target)){
|
||||||
|
//역전된 상황이다.
|
||||||
|
$result[$key] = $this->extractObjClassInfo($key, $callerFunction);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$result[$key] = $target;
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function extractObjClassInfoFromGameConst(string $gameConstKey, callable $callerFunction): array
|
||||||
|
{
|
||||||
|
$gameConstKeyList = explode(".", $gameConstKey);
|
||||||
|
$target = (GameConst::${$gameConstKeyList[0]}) ?? [];
|
||||||
|
foreach(\array_slice($gameConstKeyList, 1) as $gameConstSubKey){
|
||||||
|
$target = $target[$gameConstSubKey] ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($target)) {
|
||||||
|
return [$target => $this->extractObjClassInfo($target, $callerFunction)];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($target)) {
|
||||||
|
throw new \RuntimeException("GameConst::{$gameConstKey}의 값이 {$target}임");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->extractObjClassInfoFromArray($target, $callerFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function genConstData()
|
||||||
|
{
|
||||||
|
$gameConstKeys = [
|
||||||
|
'nationType' => [
|
||||||
|
'\sammo\buildNationTypeClass',
|
||||||
|
['availableNationType', 'neutralNationType']
|
||||||
|
],
|
||||||
|
'specialDomestic' => [
|
||||||
|
'\sammo\buildGeneralSpecialDomesticClass',
|
||||||
|
['defaultSpecialDomestic', 'availableSpecialDomestic', 'optionalSpecialDomestic']
|
||||||
|
],
|
||||||
|
'specialWar' => [
|
||||||
|
'\sammo\buildGeneralSpecialWarClass',
|
||||||
|
['defaultSpecialWar', 'availableSpecialWar', 'optionalSpecialWar']
|
||||||
|
],
|
||||||
|
'personality' => [
|
||||||
|
'\sammo\buildPersonalityClass',
|
||||||
|
['neutralPersonality', 'availablePersonality', 'optionalPersonality']
|
||||||
|
],
|
||||||
|
'item' => [
|
||||||
|
'\sammo\buildItemClass',
|
||||||
|
['allItems'],
|
||||||
|
1
|
||||||
|
],
|
||||||
|
];
|
||||||
|
//GameConst 중 BaseCommand는 시간 흐름, 장수에 따라 정보가 달라지므로 따로 처리해야함
|
||||||
|
|
||||||
|
|
||||||
|
$iActionInfo = [];
|
||||||
|
$iActionKeyMap = [];
|
||||||
|
foreach ($gameConstKeys as $mappedKey => $callerTarget) {
|
||||||
|
$flatLevel = 0;
|
||||||
|
if (is_array($callerTarget)) {
|
||||||
|
$callerFunction = $callerTarget[0];
|
||||||
|
$gameConstSubKey = $callerTarget[1];
|
||||||
|
if(count($callerTarget) > 2){
|
||||||
|
/** @var int */
|
||||||
|
$flatLevel = $callerTarget[2];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$gameConstSubKey = [$mappedKey];
|
||||||
|
$callerFunction = $callerTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_callable($callerFunction)) {
|
||||||
|
throw new \RuntimeException("{$mappedKey} => {$callerFunction}이 callable이 아님");
|
||||||
|
}
|
||||||
|
|
||||||
|
$actionInfo = [];
|
||||||
|
foreach ($gameConstSubKey as $key) {
|
||||||
|
$appendInfo = $this->extractObjClassInfoFromGameConst($key, $callerFunction);
|
||||||
|
$actionInfo = array_merge($actionInfo, $appendInfo);
|
||||||
|
$iActionKeyMap[$key] = $mappedKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($flatLevel > 0){
|
||||||
|
foreach(range(0, $flatLevel - 1) as $tryFlatLevel){
|
||||||
|
$actionInfo = array_merge(...array_values($actionInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$iActionInfo[$mappedKey] = $actionInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
$crewtypeMap = [];
|
||||||
|
foreach(GameUnitConst::all() as $crewtypeObj){
|
||||||
|
$crewtypeMap[$crewtypeObj->id] = [
|
||||||
|
'value'=>(string)$crewtypeObj->id,
|
||||||
|
'name'=>$crewtypeObj->name,
|
||||||
|
'info'=>$crewtypeObj->getInfo(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$iActionInfo['crewtype'] = $crewtypeMap;
|
||||||
|
|
||||||
|
|
||||||
|
return [
|
||||||
|
'gameConst' => get_class_vars('\sammo\GameConst'),
|
||||||
|
'gameUnitConst' => GameUnitConst::all(),
|
||||||
|
'cityConst' => CityConst::all(),
|
||||||
|
'cityConstMap' => [
|
||||||
|
'region' => CityConst::$regionMap,
|
||||||
|
'level' => CityConst::$levelMap,
|
||||||
|
],
|
||||||
|
'iActionInfo' => $iActionInfo,
|
||||||
|
'iActionKeyMap' => $iActionKeyMap,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||||
|
{
|
||||||
|
$cacheDir = $this->rootPath . '/data/file_cache';
|
||||||
|
|
||||||
|
if (!prepareDir($cacheDir)) {
|
||||||
|
throw new RuntimeException('cache 폴더 없음');
|
||||||
|
}
|
||||||
|
$storage = new \Nette\Caching\Storages\FileStorage($cacheDir);
|
||||||
|
$cache = new Cache($storage);
|
||||||
|
|
||||||
|
$currentCacheKey = $this->tryCache();
|
||||||
|
if($modifiedSince !== null && $currentCacheKey->lastModified == $modifiedSince){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if($reqEtag !== null && $currentCacheKey->etag == $reqEtag){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$constCache = $this->readCache($cache);
|
||||||
|
if ($constCache !== null) {
|
||||||
|
return [
|
||||||
|
'result' => true,
|
||||||
|
'cacheKey' => $this->getCacheKey(),
|
||||||
|
'data' => $constCache,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$constCache = $this->genConstData();
|
||||||
|
$cache->save(static::CACHE_KEY, Json::encode([
|
||||||
|
'cacheKey' => $this->getCacheKey(),
|
||||||
|
'data' => $constCache
|
||||||
|
]));
|
||||||
|
|
||||||
|
return [
|
||||||
|
'result' => true,
|
||||||
|
'cacheKey' => $this->getCacheKey(),
|
||||||
|
'data' => $constCache,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,285 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\API\Nation;
|
||||||
|
|
||||||
|
use sammo\DB;
|
||||||
|
use sammo\General;
|
||||||
|
use sammo\Session;
|
||||||
|
use sammo\Util;
|
||||||
|
use sammo\Validator;
|
||||||
|
|
||||||
|
use function sammo\calcLeadershipBonus;
|
||||||
|
use function sammo\checkLimit;
|
||||||
|
use function sammo\checkSecretPermission;
|
||||||
|
use function sammo\getBillByLevel;
|
||||||
|
use function sammo\getDedLevelText;
|
||||||
|
use function sammo\getGenChar;
|
||||||
|
use function sammo\getGeneralSpecialDomesticName;
|
||||||
|
use function sammo\getGeneralSpecialWarName;
|
||||||
|
use function sammo\getHonor;
|
||||||
|
use function sammo\getNationStaticInfo;
|
||||||
|
use function sammo\getOfficerLevelText;
|
||||||
|
use function sammo\increaseRefresh;
|
||||||
|
|
||||||
|
class GeneralList extends \sammo\BaseAPI
|
||||||
|
{
|
||||||
|
private int $permission;
|
||||||
|
|
||||||
|
static $viewColumns = [
|
||||||
|
'no' => 0,
|
||||||
|
'name' => 0,
|
||||||
|
'nation' => 0,
|
||||||
|
'npc' => 0,
|
||||||
|
'injury' => 0,
|
||||||
|
'leadership' => 0,
|
||||||
|
'strength' => 0,
|
||||||
|
'intel' => 0,
|
||||||
|
'explevel' => 0,
|
||||||
|
'dedlevel' => 0,
|
||||||
|
'gold' => 0,
|
||||||
|
'rice' => 0,
|
||||||
|
'killturn' => 0,
|
||||||
|
'picture' => 0,
|
||||||
|
'imgsvr' => 0,
|
||||||
|
'age' => 0,
|
||||||
|
'special' => 0,
|
||||||
|
'special2' => 0,
|
||||||
|
'personal' => 0,
|
||||||
|
'belong' => 0,
|
||||||
|
'connect' => 0,
|
||||||
|
|
||||||
|
|
||||||
|
'city' => 1,
|
||||||
|
'experience' => 1,
|
||||||
|
'dedication' => 1,
|
||||||
|
|
||||||
|
'officer_level' => 2,
|
||||||
|
'officer_city' => 2,
|
||||||
|
'defence_train' => 2,
|
||||||
|
'troop' => 2,
|
||||||
|
'crewtype' => 2,
|
||||||
|
'crew' => 2,
|
||||||
|
'train' => 2,
|
||||||
|
'atmos' => 2,
|
||||||
|
'turntime' => 2,
|
||||||
|
'horse' => 2,
|
||||||
|
'weapon' => 2,
|
||||||
|
'book' => 2,
|
||||||
|
'item' => 2,
|
||||||
|
'recent_war' => 2,
|
||||||
|
|
||||||
|
'aux' => 2,
|
||||||
|
|
||||||
|
|
||||||
|
'owner_name' => 9,//안씀.
|
||||||
|
|
||||||
|
//RANK
|
||||||
|
'warnum' => 2,
|
||||||
|
'killnum' => 2,
|
||||||
|
'deathnum' => 2,
|
||||||
|
'killcrew' => 2,
|
||||||
|
'deathcrew' => 2,
|
||||||
|
'firenum' => 2,
|
||||||
|
];
|
||||||
|
|
||||||
|
static $columnRemap = [
|
||||||
|
'special' => 'specialDomestic',
|
||||||
|
'special2' => 'specialWar',
|
||||||
|
'aux' => null,
|
||||||
|
];
|
||||||
|
|
||||||
|
static $customViewColumns = [
|
||||||
|
'officerLevel' => 0,
|
||||||
|
'officerLevelText' => 0,
|
||||||
|
'lbonus' => 0,
|
||||||
|
'ownerName' => 0,
|
||||||
|
'honorText' => 0,
|
||||||
|
'dedLevelText' => 0,
|
||||||
|
'bill' => 0,
|
||||||
|
'reservedCommand' => 2,
|
||||||
|
|
||||||
|
'autorun_limit' => 2,
|
||||||
|
];
|
||||||
|
|
||||||
|
public function validateArgs(): ?string
|
||||||
|
{
|
||||||
|
//TODO: 장기적으로는 요청에 따라 반환해야...
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequiredSessionMode(): int
|
||||||
|
{
|
||||||
|
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getOfficerLevel($rawGeneral)
|
||||||
|
{
|
||||||
|
$level = $rawGeneral['officer_level'];
|
||||||
|
if ($level >= 5) {
|
||||||
|
return $level;
|
||||||
|
}
|
||||||
|
if ($this->permission > 1) {
|
||||||
|
return $level;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch(Session $session, ?\DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||||
|
{
|
||||||
|
increaseRefresh("세력장수", 1);
|
||||||
|
|
||||||
|
$db = DB::db();
|
||||||
|
|
||||||
|
$gameStor = \sammo\KVStorage::getStorage($db, 'game_env');
|
||||||
|
$env = $gameStor->getValues(['year', 'month', 'turntime', 'turnterm', 'autorun_user', 'killturn']);
|
||||||
|
|
||||||
|
$me = $db->queryFirstRow('SELECT con, turntime, belong, nation, officer_level, permission, penalty FROM general WHERE owner=%i', $session->getUserID());
|
||||||
|
$con = checkLimit($me['con']);
|
||||||
|
if ($con >= 2) {
|
||||||
|
return '접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.';
|
||||||
|
}
|
||||||
|
|
||||||
|
$nationID = $me['nation'];
|
||||||
|
$this->permission = checkSecretPermission($me, true);
|
||||||
|
|
||||||
|
$nationArr = getNationStaticInfo($nationID);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[$queryColumns, $rankColumns] = General::mergeQueryColumn(array_keys(static::$viewColumns), 1);
|
||||||
|
|
||||||
|
$rawGeneralList = Util::convertArrayToDict($db->query('SELECT %l from general WHERE nation = %i ORDER BY turntime ASC', Util::formatListOfBackticks($queryColumns), $nationID), 'no');
|
||||||
|
|
||||||
|
$reservedCommand = [];
|
||||||
|
if ($this->permission >= 2) {
|
||||||
|
$nonNPCGeneralIDList = [];
|
||||||
|
foreach ($rawGeneralList as $rawGeneral) {
|
||||||
|
if ($rawGeneral['npc'] < 2) {
|
||||||
|
$nonNPCGeneralIDList[] = $rawGeneral['no'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$rawTurnList = $db->query(
|
||||||
|
'SELECT general_id, turn_idx, action, arg, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id asc, turn_idx asc',
|
||||||
|
$nonNPCGeneralIDList
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($rawTurnList as $rawTurn) {
|
||||||
|
[
|
||||||
|
'general_id' => $generalID,
|
||||||
|
'action' => $action,
|
||||||
|
'arg' => $arg,
|
||||||
|
'brief' => $brief,
|
||||||
|
] = $rawTurn;
|
||||||
|
if (!key_exists($generalID, $reservedCommand)) {
|
||||||
|
$reservedCommand[$generalID] = [];
|
||||||
|
}
|
||||||
|
$reservedCommand[$generalID][] = [
|
||||||
|
'action' => $action,
|
||||||
|
'arg' => $arg,
|
||||||
|
'brief' => $brief
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$rankList = [];
|
||||||
|
if ($rankColumns) {
|
||||||
|
$rawRankList = $db->query('SELECT general_id, `type`, `value` FROM rank_data WHERE nation_id = %i AND `type` IN %ls', $nationID, $rankColumns);
|
||||||
|
foreach ($rawRankList as $rawRank) {
|
||||||
|
[
|
||||||
|
'general_id' => $generalID,
|
||||||
|
'type' => $type,
|
||||||
|
'value' => $value
|
||||||
|
] = $rawRank;
|
||||||
|
|
||||||
|
if (!key_exists($generalID, $rankList)) {
|
||||||
|
$rankList[$generalID] = [];
|
||||||
|
}
|
||||||
|
$rankList[$generalID][$type] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$getRankVar = fn ($key) => (fn ($rawGeneral) => (($rankList[$rawGeneral['no']] ?? [])[$key] ?? 0));
|
||||||
|
|
||||||
|
$specialViewFilter = [
|
||||||
|
'officerLevel' => fn ($rawGeneral) => $this->getOfficerLevel($rawGeneral),
|
||||||
|
'officerLevelText' => fn ($rawGeneral) => getOfficerLevelText($this->getOfficerLevel($rawGeneral), $nationArr['level']),
|
||||||
|
'lbonus' => fn ($rawGeneral) => calcLeadershipBonus($rawGeneral['officer_level'], $nationArr['level']),
|
||||||
|
'ownerName' => fn ($rawGeneral) => ($rawGeneral['npc'] != 1) ? null : $rawGeneral['owner_name'],
|
||||||
|
'honorText' => fn ($rawGeneral) => getHonor($rawGeneral['experience']),
|
||||||
|
'dedLevelText' => fn ($rawGeneral) => getDedLevelText($rawGeneral['dedlevel']),
|
||||||
|
//'0000-00-00 11:23';
|
||||||
|
'turntime' => fn ($rawGeneral) => substr($rawGeneral['turntime'], 0, 19),
|
||||||
|
'recent_war' => fn ($rawGeneral) => substr($rawGeneral['recent_war'], 0, 19),
|
||||||
|
'bill' => fn ($rawGeneral) => getBillByLevel($rawGeneral['dedlevel']),
|
||||||
|
'reservedCommand' => fn ($rawGeneral) => $reservedCommand[$rawGeneral['no']] ?? null,
|
||||||
|
'autorun_limit' => fn ($rawGeneral) => ($rawGeneral['aux'] ?? [])['autorun_limit'] ?? 0,
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($rankColumns as $rankKey) {
|
||||||
|
$specialViewFilter[$rankKey] = $getRankVar($rankKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$resultColumns = [];
|
||||||
|
foreach (static::$viewColumns as $column => $reqPermission) {
|
||||||
|
if ($reqPermission > $this->permission) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (key_exists($column, static::$columnRemap)) {
|
||||||
|
$newColumn = static::$columnRemap[$column];
|
||||||
|
if($newColumn !== null){
|
||||||
|
$resultColumns[$newColumn] = $column;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$resultColumns[$column] = $column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (static::$customViewColumns as $column => $reqPermission) {
|
||||||
|
if ($reqPermission > $this->permission) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$resultColumns[$column] = $column;
|
||||||
|
}
|
||||||
|
|
||||||
|
$generalList = [];
|
||||||
|
foreach ($rawGeneralList as $rawGeneral) {
|
||||||
|
//General 생성?
|
||||||
|
if (key_exists('aux', $rawGeneral)) {
|
||||||
|
$rawGeneral['aux'] = \sammo\JSON::decode($rawGeneral['aux']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$item = [];
|
||||||
|
foreach ($resultColumns as $column) {
|
||||||
|
if (key_exists($column, $specialViewFilter)) {
|
||||||
|
$value = $specialViewFilter[$column]($rawGeneral);
|
||||||
|
} else {
|
||||||
|
$value = $rawGeneral[$column];
|
||||||
|
}
|
||||||
|
$item[] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$generalList[] = $item;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($this->permission >= 2){
|
||||||
|
$troops = $db->queryAllLists('SELECT troop_leader,name FROM troop WHERE nation = %i', $nationID);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$troops = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
'result' => true,
|
||||||
|
'permission' => $this->permission,
|
||||||
|
'column' => array_keys($resultColumns),
|
||||||
|
'list' => $generalList,
|
||||||
|
'troops' => $troops,
|
||||||
|
'env' => $env,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -117,6 +117,8 @@ class GetReservedCommand extends \sammo\BaseAPI
|
|||||||
'autorun_limit' => $generalObj->getAuxVar('autorun_limit'),
|
'autorun_limit' => $generalObj->getAuxVar('autorun_limit'),
|
||||||
'officerLevel' => $me['officer_level'],
|
'officerLevel' => $me['officer_level'],
|
||||||
'commandList' => getChiefCommandTable($generalObj),
|
'commandList' => getChiefCommandTable($generalObj),
|
||||||
|
'mapName' => GameConst::$mapName,
|
||||||
|
'unitSet' => GameConst::$unitSet,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\API\NationCommand;
|
||||||
|
|
||||||
|
use sammo\Session;
|
||||||
|
use DateTimeInterface;
|
||||||
|
use sammo\GameConst;
|
||||||
|
use sammo\Util;
|
||||||
|
use sammo\Validator;
|
||||||
|
|
||||||
|
use function sammo\setNationCommand;
|
||||||
|
|
||||||
|
class ReserveBulkCommand extends \sammo\BaseAPI
|
||||||
|
{
|
||||||
|
public function validateArgs(): ?string
|
||||||
|
{
|
||||||
|
foreach ($this->args as $idx => $turn) {
|
||||||
|
$v = new Validator($turn);
|
||||||
|
$v->rule('required', [
|
||||||
|
'action',
|
||||||
|
'turnList'
|
||||||
|
])
|
||||||
|
->rule('lengthMin', 'action', 1)
|
||||||
|
->rule('integerArray', 'turnList');
|
||||||
|
|
||||||
|
if (!$v->validate()) {
|
||||||
|
return "{$idx}:{$v->errorStr()}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequiredSessionMode(): int
|
||||||
|
{
|
||||||
|
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||||
|
{
|
||||||
|
$briefList = [];
|
||||||
|
foreach ($this->args as $idx => $turn) {
|
||||||
|
$action = $turn['action'];
|
||||||
|
$turnList = $turn['turnList'];
|
||||||
|
$arg = $turn['arg'] ?? [];
|
||||||
|
|
||||||
|
if (!$turnList) {
|
||||||
|
return "{$idx}: 턴이 입력되지 않았습니다";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array($action, Util::array_flatten(GameConst::$availableChiefCommand))) {
|
||||||
|
return "{$idx}: 사용할 수 없는 커맨드입니다.";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($arg)) {
|
||||||
|
return "{$idx}: 올바른 arg 형태가 아닙니다.";
|
||||||
|
}
|
||||||
|
$partialResult = setNationCommand($session->generalID, $turnList, $action, $arg);
|
||||||
|
if(!$partialResult['result']){
|
||||||
|
return [
|
||||||
|
'result' => false,
|
||||||
|
'briefList' => $briefList,
|
||||||
|
'errorIdx' => $idx,
|
||||||
|
'reason' => $partialResult['reason']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
$briefList[$idx] = $partialResult['brief'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'result' => true,
|
||||||
|
'briefList' => $briefList,
|
||||||
|
'reason' => 'success'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ class che_보물_도기 extends \sammo\BaseItem
|
|||||||
|
|
||||||
protected $rawName = '도기';
|
protected $rawName = '도기';
|
||||||
protected $name = '도기(보물)';
|
protected $name = '도기(보물)';
|
||||||
protected $info = '[개인] 판매 시 국고에 금, 쌀 중 하나를 추가 (+10,000, 5년마다 +10,000)';
|
protected $info = '[개인] 판매 시 장수 소지금과 국고에 금, 쌀 중 하나를 추가 (총 +10,000, 5년마다 +10,000)';
|
||||||
protected $cost = 200;
|
protected $cost = 200;
|
||||||
protected $consumable = false;
|
protected $consumable = false;
|
||||||
|
|
||||||
@@ -48,15 +48,16 @@ class che_보물_도기 extends \sammo\BaseItem
|
|||||||
|
|
||||||
if ($nationId != 0) {
|
if ($nationId != 0) {
|
||||||
$db->update('nation', [
|
$db->update('nation', [
|
||||||
$resKey => $db->sqleval('%b + %i', $resKey, $score)
|
$resKey => $db->sqleval('%b + %i', $resKey, Util::toInt($score / 2))
|
||||||
], 'nation=%i', $nationId);
|
], 'nation=%i', $nationId);
|
||||||
}
|
}
|
||||||
|
$general->increaseVar($resKey, $score - Util::toInt($score / 2));
|
||||||
|
|
||||||
$score = Util::round($score);
|
$score = Util::round($score);
|
||||||
$scoreText = number_format($score, 0);
|
$scoreText = number_format($score, 0);
|
||||||
|
|
||||||
$logger = $general->getLogger();
|
$logger = $general->getLogger();
|
||||||
$logger->pushGeneralActionLog("국고에 {$resName} <C>{$scoreText}</>을 보충합니다.");
|
$logger->pushGeneralActionLog("재산과 국고에 총 {$resName} <C>{$scoreText}</>을 보충합니다.");
|
||||||
return $aux;
|
return $aux;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class che_상성보정_과실주 extends \sammo\BaseItem{
|
|||||||
|
|
||||||
protected $rawName = '과실주';
|
protected $rawName = '과실주';
|
||||||
protected $name = '과실주(상성)';
|
protected $name = '과실주(상성)';
|
||||||
protected $info = '[전투] 유리한 병종 전투시 공격력 +10%, 피해 -10%';
|
protected $info = '[전투] 대등/유리한 병종 전투시 공격력 +10%, 피해 -10%';
|
||||||
protected $cost = 200;
|
protected $cost = 200;
|
||||||
protected $consumable = false;
|
protected $consumable = false;
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ class che_상성보정_과실주 extends \sammo\BaseItem{
|
|||||||
{
|
{
|
||||||
$oppose = $unit->getOppose();
|
$oppose = $unit->getOppose();
|
||||||
$attackCoef = $unit->getCrewType()->getAttackCoef($oppose->getCrewType());
|
$attackCoef = $unit->getCrewType()->getAttackCoef($oppose->getCrewType());
|
||||||
if($attackCoef <= 1){
|
if($attackCoef < 1){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new WarUnitTriggerCaller(
|
return new WarUnitTriggerCaller(
|
||||||
|
|||||||
@@ -10,4 +10,10 @@ abstract class BaseNation implements iAction{
|
|||||||
protected $info = '';
|
protected $info = '';
|
||||||
static $pros = '';
|
static $pros = '';
|
||||||
static $cons = '';
|
static $cons = '';
|
||||||
|
|
||||||
|
public function getInfo(): string{
|
||||||
|
$pros = static::$pros;
|
||||||
|
$cons = static::$cons;
|
||||||
|
return "{$pros} {$cons}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+31
-10
@@ -26,7 +26,7 @@ class Betting
|
|||||||
return Json::encode($bettingType);
|
return Json::encode($bettingType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function purifyBettingKey(array $bettingType): array
|
public function purifyBettingKey(array $bettingType, bool $ignoreOver = false): array
|
||||||
{
|
{
|
||||||
$selectCnt = $this->info->selectCnt;
|
$selectCnt = $this->info->selectCnt;
|
||||||
sort($bettingType, SORT_NUMERIC);
|
sort($bettingType, SORT_NUMERIC);
|
||||||
@@ -39,7 +39,7 @@ class Betting
|
|||||||
throw new \InvalidArgumentException('올바르지 않은 값이 있습니다.(0 미만)' . print_r($bettingType, true));
|
throw new \InvalidArgumentException('올바르지 않은 값이 있습니다.(0 미만)' . print_r($bettingType, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Util::array_last($bettingType) >= count($this->info->candidates)) {
|
if (!$ignoreOver && Util::array_last($bettingType) >= count($this->info->candidates)) {
|
||||||
throw new \InvalidArgumentException('올바르지 않은 값이 있습니다.(초과)' . print_r($bettingType, true));
|
throw new \InvalidArgumentException('올바르지 않은 값이 있습니다.(초과)' . print_r($bettingType, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +155,19 @@ class Betting
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($subAmount == 0) {
|
if ($subAmount == 0) {
|
||||||
|
$refundList = [];
|
||||||
|
//당첨자가 아무도 없다면 무효로 하자.
|
||||||
|
foreach ($db->queryAllLists(
|
||||||
|
'SELECT general_id, user_id, amount, betting_type FROM ng_betting WHERE betting_id = %i',
|
||||||
|
$this->bettingID
|
||||||
|
) as [$generalID, $userID, $amount, $bettingTypeKey]) {
|
||||||
|
$refundList[] = [
|
||||||
|
'generalID' => $generalID,
|
||||||
|
'userID' => $userID,
|
||||||
|
'amount' => $amount,
|
||||||
|
'matchPoint' => 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,8 +246,12 @@ class Betting
|
|||||||
}
|
}
|
||||||
|
|
||||||
$remainRewardAmount = $totalAmount;
|
$remainRewardAmount = $totalAmount;
|
||||||
|
$accumulatedRewardAmount = 0;
|
||||||
|
$givenRewardAmount = $totalAmount;
|
||||||
$rewardAmount = [];
|
$rewardAmount = [];
|
||||||
foreach (Util::range($selectCnt, 0, -1) as $matchPoint) {
|
foreach (Util::range($selectCnt, 0, -1) as $matchPoint) {
|
||||||
|
$givenRewardAmount /= 2;
|
||||||
|
$accumulatedRewardAmount += $givenRewardAmount;
|
||||||
if (count($subWinners[$matchPoint]) == 0) {
|
if (count($subWinners[$matchPoint]) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -242,17 +259,21 @@ class Betting
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$givenRewardAmount = $remainRewardAmount / 2;
|
$rewardAmount[$matchPoint] = $accumulatedRewardAmount;
|
||||||
$rewardAmount[$matchPoint] = $givenRewardAmount;
|
$remainRewardAmount -= $accumulatedRewardAmount;
|
||||||
$remainRewardAmount -= $givenRewardAmount; // /2가 아니라 다른 값이 될 경우를 대비..
|
$accumulatedRewardAmount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Util::range(1, $selectCnt + 1) as $matchPoint) {
|
//남은 상금은 '당첨자'에게 몰아준다.
|
||||||
if (!key_exists($matchPoint, $rewardAmount)) {
|
//당첨자가 아무도 없다면, 0개 맞춘 그룹에게 돌아간다.
|
||||||
continue;
|
if($rewardAmount){
|
||||||
|
foreach(Util::range($selectCnt, -1, -1) as $matchPoint){
|
||||||
|
if (!key_exists($matchPoint, $rewardAmount)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$rewardAmount[$matchPoint] += $rewardAmount;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
$rewardAmount[$matchPoint] += $remainRewardAmount;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|||||||
@@ -173,7 +173,6 @@ class che_강행 extends Command\GeneralCommand
|
|||||||
public function exportJSVars(): array
|
public function exportJSVars(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'cities' => \sammo\JSOptionsForCities(),
|
'cities' => \sammo\JSOptionsForCities(),
|
||||||
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 3),
|
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 3),
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ class che_랜덤임관 extends Command\GeneralCommand
|
|||||||
if ($notIn) {
|
if ($notIn) {
|
||||||
|
|
||||||
$rawGeneralsCnt = $db->query(
|
$rawGeneralsCnt = $db->query(
|
||||||
"SELECT g.`nation`, n.`gennum`, n.name, SUM((ra.value + 1000)/(rb.value + 1000)*(CASE WHEN g.`leadership` >= 40 THEN g.`leadership` ELSE 0 END)) AS warpower, SUM(SQRT(g.intel * g.strength) * 2 + g.leadership / 2)/5 AS develpower
|
"SELECT g.`nation`, n.`gennum`, n.name, SUM((ra.value + 1000)/(rb.value + 1000)*(CASE WHEN g.`npc` < 2 THEN 1.2 ELSE 1 END)*(CASE WHEN g.`leadership` >= 40 THEN g.`leadership` ELSE 0 END)) AS warpower, SUM(SQRT(g.intel * g.strength) * 2 + g.leadership / 2)/5 AS develpower
|
||||||
FROM general AS g
|
FROM general AS g
|
||||||
LEFT JOIN `rank_data` AS ra ON g.`no` = ra.general_id AND ra.`type` = 'killcrew_person'
|
LEFT JOIN `rank_data` AS ra ON g.`no` = ra.general_id AND ra.`type` = 'killcrew_person'
|
||||||
LEFT JOIN `rank_data` AS rb ON g.`no` = rb.general_id AND rb.`type` = 'deathcrew_person'
|
LEFT JOIN `rank_data` AS rb ON g.`no` = rb.general_id AND rb.`type` = 'deathcrew_person'
|
||||||
@@ -195,7 +195,7 @@ class che_랜덤임관 extends Command\GeneralCommand
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$rawGeneralsCnt = $db->query(
|
$rawGeneralsCnt = $db->query(
|
||||||
"SELECT g.`nation`, n.`gennum`, n.name, SUM((ra.value + 100)/(rb.value + 100)*(CASE WHEN g.`leadership` >= 40 THEN g.`leadership` ELSE 0 END)) AS warpower, SUM(SQRT(g.intel * g.strength) * 2 + g.leadership / 2)/5 AS develpower
|
"SELECT g.`nation`, n.`gennum`, n.name, SUM((ra.value + 100)/(rb.value + 100)*(CASE WHEN g.`npc` < 2 THEN 1.2 ELSE 1 END)*(CASE WHEN g.`leadership` >= 40 THEN g.`leadership` ELSE 0 END)) AS warpower, SUM(SQRT(g.intel * g.strength) * 2 + g.leadership / 2)/5 AS develpower
|
||||||
FROM general AS g
|
FROM general AS g
|
||||||
LEFT JOIN `rank_data` AS ra ON g.`no` = ra.general_id AND ra.`type` = 'killcrew_person'
|
LEFT JOIN `rank_data` AS ra ON g.`no` = ra.general_id AND ra.`type` = 'killcrew_person'
|
||||||
LEFT JOIN `rank_data` AS rb ON g.`no` = rb.general_id AND rb.`type` = 'deathcrew_person'
|
LEFT JOIN `rank_data` AS rb ON g.`no` = rb.general_id AND rb.`type` = 'deathcrew_person'
|
||||||
|
|||||||
@@ -181,7 +181,6 @@ class che_이동 extends Command\GeneralCommand
|
|||||||
public function exportJSVars(): array
|
public function exportJSVars(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'cities' => \sammo\JSOptionsForCities(),
|
'cities' => \sammo\JSOptionsForCities(),
|
||||||
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 1),
|
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 1),
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ class che_임관 extends Command\GeneralCommand
|
|||||||
$general->setVar('officer_level', 1);
|
$general->setVar('officer_level', 1);
|
||||||
$general->setVar('officer_city', 0);
|
$general->setVar('officer_city', 0);
|
||||||
$general->setVar('belong', 1);
|
$general->setVar('belong', 1);
|
||||||
|
$general->setVar('troop', 0);
|
||||||
|
|
||||||
if ($this->destGeneralObj !== null) {
|
if ($this->destGeneralObj !== null) {
|
||||||
$general->setVar('city', $this->destGeneralObj->getCityID());
|
$general->setVar('city', $this->destGeneralObj->getCityID());
|
||||||
@@ -200,6 +201,7 @@ class che_임관 extends Command\GeneralCommand
|
|||||||
|
|
||||||
$rawNationList = Util::convertArrayToDict($db->query('SELECT nation,`name`,color,gennum,`power` FROM nation'), 'nation');
|
$rawNationList = Util::convertArrayToDict($db->query('SELECT nation,`name`,color,gennum,`power` FROM nation'), 'nation');
|
||||||
$scoutMsgs = KVStorage::getValuesFromInterNamespace($db, 'nation_env', 'scout_msg');
|
$scoutMsgs = KVStorage::getValuesFromInterNamespace($db, 'nation_env', 'scout_msg');
|
||||||
|
$nationList = [];
|
||||||
foreach ($scoutMsgs as $destNationID => $scoutMsg) {
|
foreach ($scoutMsgs as $destNationID => $scoutMsg) {
|
||||||
$rawNationList[$destNationID]['scoutmsg'] = $scoutMsg;
|
$rawNationList[$destNationID]['scoutmsg'] = $scoutMsg;
|
||||||
}
|
}
|
||||||
@@ -223,7 +225,6 @@ class che_임관 extends Command\GeneralCommand
|
|||||||
$nationList[] = $nationTarget;
|
$nationList[] = $nationTarget;
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'nationList' => $nationList,
|
'nationList' => $nationList,
|
||||||
'startYear' => $this->env['startyear'],
|
'startYear' => $this->env['startyear'],
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use \sammo\{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use function sammo\getAllNationStaticInfo;
|
use function sammo\getAllNationStaticInfo;
|
||||||
use function \sammo\getColoredName;
|
use function \sammo\formatName;
|
||||||
use function \sammo\tryUniqueItemLottery;
|
use function \sammo\tryUniqueItemLottery;
|
||||||
use function \sammo\getInvitationList;
|
use function \sammo\getInvitationList;
|
||||||
use function \sammo\getNationStaticInfo;
|
use function \sammo\getNationStaticInfo;
|
||||||
|
|||||||
@@ -228,7 +228,6 @@ class che_첩보 extends Command\GeneralCommand
|
|||||||
public function exportJSVars(): array
|
public function exportJSVars(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'cities' => \sammo\JSOptionsForCities(),
|
'cities' => \sammo\JSOptionsForCities(),
|
||||||
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 3),
|
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 3),
|
||||||
|
|||||||
@@ -244,7 +244,6 @@ class che_출병 extends Command\GeneralCommand
|
|||||||
public function exportJSVars(): array
|
public function exportJSVars(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'cities' => \sammo\JSOptionsForCities(),
|
'cities' => \sammo\JSOptionsForCities(),
|
||||||
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 1),
|
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 1),
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ class che_하야 extends Command\GeneralCommand{
|
|||||||
|
|
||||||
$general = $this->generalObj;
|
$general = $this->generalObj;
|
||||||
$date = $general->getTurnTime($general::TURNTIME_HM);
|
$date = $general->getTurnTime($general::TURNTIME_HM);
|
||||||
|
$generalID = $general->getID();
|
||||||
$generalName = $general->getName();
|
$generalName = $general->getName();
|
||||||
$josaYi = JosaUtil::pick($generalName, '이');
|
$josaYi = JosaUtil::pick($generalName, '이');
|
||||||
|
|
||||||
@@ -101,6 +102,17 @@ class che_하야 extends Command\GeneralCommand{
|
|||||||
$general->setVar('officer_city', 0);
|
$general->setVar('officer_city', 0);
|
||||||
$general->setVar('belong', 0);
|
$general->setVar('belong', 0);
|
||||||
$general->setVar('makelimit', 12);
|
$general->setVar('makelimit', 12);
|
||||||
|
|
||||||
|
//부대장일 경우
|
||||||
|
if($general->getVar('troop') == $generalID){
|
||||||
|
// 모두 탈퇴
|
||||||
|
$db->update('general', [
|
||||||
|
'troop'=>0,
|
||||||
|
], 'troop = %i', $generalID);
|
||||||
|
$db->delete('troop', 'troop_leader=%i', $generalID);
|
||||||
|
}
|
||||||
|
$general->setVar('troop', 0);
|
||||||
|
|
||||||
$general->increaseInheritancePoint('active_action', 1);
|
$general->increaseInheritancePoint('active_action', 1);
|
||||||
|
|
||||||
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
||||||
|
|||||||
@@ -281,6 +281,7 @@ class che_화계 extends Command\GeneralCommand
|
|||||||
|
|
||||||
$prob = GameConst::$sabotageDefaultProb + $this->calcSabotageAttackProb() - $this->calcSabotageDefenceProb($destCityGeneralList);
|
$prob = GameConst::$sabotageDefaultProb + $this->calcSabotageAttackProb() - $this->calcSabotageDefenceProb($destCityGeneralList);
|
||||||
$prob /= $dist;
|
$prob /= $dist;
|
||||||
|
$prob = Util::valueFit($prob, 0, 0.5);
|
||||||
|
|
||||||
if (!Util::randBool($prob)) {
|
if (!Util::randBool($prob)) {
|
||||||
$josaYi = JosaUtil::pick($commandName, '이');
|
$josaYi = JosaUtil::pick($commandName, '이');
|
||||||
@@ -341,7 +342,6 @@ class che_화계 extends Command\GeneralCommand
|
|||||||
public function exportJSVars(): array
|
public function exportJSVars(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'cities' => \sammo\JSOptionsForCities(),
|
'cities' => \sammo\JSOptionsForCities(),
|
||||||
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 3),
|
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 3),
|
||||||
|
|||||||
@@ -221,7 +221,6 @@ class che_급습 extends Command\NationCommand
|
|||||||
$nationList[] = $nationTarget;
|
$nationList[] = $nationTarget;
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'nationList' => $nationList,
|
'nationList' => $nationList,
|
||||||
'startYear' => $this->env['startyear'],
|
'startYear' => $this->env['startyear'],
|
||||||
|
|||||||
@@ -291,7 +291,6 @@ class che_물자원조 extends Command\NationCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'nationList' => $nationList,
|
'nationList' => $nationList,
|
||||||
'currentNationLevel' => $currentNationLevel,
|
'currentNationLevel' => $currentNationLevel,
|
||||||
|
|||||||
@@ -177,7 +177,6 @@ class che_발령 extends Command\NationCommand
|
|||||||
$troops = Util::convertArrayToDict($db->query('SELECT * FROM troop WHERE nation=%i', $nationID), 'troop_leader');
|
$troops = Util::convertArrayToDict($db->query('SELECT * FROM troop WHERE nation=%i', $nationID), 'troop_leader');
|
||||||
$destRawGenerals = $db->queryAllLists('SELECT no,name,officer_level,npc,gold,rice,leadership,strength,intel,city,crew,train,atmos,troop FROM general WHERE nation = %i ORDER BY npc,binary(name)', $nationID);
|
$destRawGenerals = $db->queryAllLists('SELECT no,name,officer_level,npc,gold,rice,leadership,strength,intel,city,crew,train,atmos,troop FROM general WHERE nation = %i ORDER BY npc,binary(name)', $nationID);
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 1),
|
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 1),
|
||||||
'cities' => \sammo\JSOptionsForCities(),
|
'cities' => \sammo\JSOptionsForCities(),
|
||||||
|
|||||||
@@ -156,11 +156,8 @@ class che_백성동원 extends Command\NationCommand
|
|||||||
'wall' => $db->sqleval('GREATEST(wall_max * 0.8, wall)'),
|
'wall' => $db->sqleval('GREATEST(wall_max * 0.8, wall)'),
|
||||||
], 'city=%i', $destCityID);
|
], 'city=%i', $destCityID);
|
||||||
|
|
||||||
$josaYiNation = JosaUtil::pick($nationName, '이');
|
|
||||||
|
|
||||||
|
|
||||||
$logger->pushGeneralHistoryLog('<M>백성동원</>을 발동');
|
$logger->pushGeneralHistoryLog('<M>백성동원</>을 발동');
|
||||||
$logger->pushNationalHistoryLog("<L><b>【전략】</b></><D><b>{$nationName}</b></>{$josaYiNation} <G><b>{$destCityName}</b></>에 <M>백성동원</>을 하였습니다.");
|
$logger->pushNationalHistoryLog("<Y>{$generalName}</>{$josaYi} <G><b>{$destCityName}</b></>에 <M>백성동원</>을 발동");
|
||||||
|
|
||||||
$db->update('nation', [
|
$db->update('nation', [
|
||||||
'strategic_cmd_limit' => $this->generalObj->onCalcStrategic($this->getName(), 'globalDelay', 9)
|
'strategic_cmd_limit' => $this->generalObj->onCalcStrategic($this->getName(), 'globalDelay', 9)
|
||||||
@@ -175,7 +172,6 @@ class che_백성동원 extends Command\NationCommand
|
|||||||
public function exportJSVars(): array
|
public function exportJSVars(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'cities' => \sammo\JSOptionsForCities(),
|
'cities' => \sammo\JSOptionsForCities(),
|
||||||
'distanceList' => new \stdClass(),
|
'distanceList' => new \stdClass(),
|
||||||
|
|||||||
@@ -101,13 +101,13 @@ class che_불가침제의 extends Command\NationCommand
|
|||||||
|
|
||||||
$nationID = $this->nation['nation'];
|
$nationID = $this->nation['nation'];
|
||||||
|
|
||||||
if ($reqMonth < $currentMonth + 12) {
|
if ($reqMonth < $currentMonth + 6) {
|
||||||
$this->permissionConstraints = [
|
$this->permissionConstraints = [
|
||||||
ConstraintHelper::AlwaysFail('기한은 1년 이상이어야 합니다.')
|
ConstraintHelper::AlwaysFail('기한은 6개월 이상이어야 합니다.')
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->fullConditionConstraints = [
|
$this->fullConditionConstraints = [
|
||||||
ConstraintHelper::AlwaysFail('기한은 1년 이상이어야 합니다.')
|
ConstraintHelper::AlwaysFail('기한은 6개월 이상이어야 합니다.')
|
||||||
];
|
];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -255,7 +255,6 @@ class che_불가침제의 extends Command\NationCommand
|
|||||||
$nationList[] = $nationTarget;
|
$nationList[] = $nationTarget;
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'nationList' => $nationList,
|
'nationList' => $nationList,
|
||||||
'startYear' => $this->env['startyear'],
|
'startYear' => $this->env['startyear'],
|
||||||
|
|||||||
@@ -200,7 +200,6 @@ class che_불가침파기제의 extends Command\NationCommand{
|
|||||||
$nationList[] = $nationTarget;
|
$nationList[] = $nationTarget;
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'nationList' => $nationList,
|
'nationList' => $nationList,
|
||||||
'startYear' => $this->env['startyear'],
|
'startYear' => $this->env['startyear'],
|
||||||
|
|||||||
@@ -219,7 +219,6 @@ class che_선전포고 extends Command\NationCommand
|
|||||||
$nationList[] = $nationTarget;
|
$nationList[] = $nationTarget;
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'nationList' => $nationList,
|
'nationList' => $nationList,
|
||||||
'startYear' => $this->env['startyear'],
|
'startYear' => $this->env['startyear'],
|
||||||
|
|||||||
@@ -199,7 +199,6 @@ class che_수몰 extends Command\NationCommand
|
|||||||
public function exportJSVars(): array
|
public function exportJSVars(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'cities' => \sammo\JSOptionsForCities(),
|
'cities' => \sammo\JSOptionsForCities(),
|
||||||
'distanceList' => new \stdClass(),
|
'distanceList' => new \stdClass(),
|
||||||
|
|||||||
@@ -224,7 +224,6 @@ class che_이호경식 extends Command\NationCommand
|
|||||||
$nationList[] = $nationTarget;
|
$nationList[] = $nationTarget;
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'nationList' => $nationList,
|
'nationList' => $nationList,
|
||||||
'startYear' => $this->env['startyear'],
|
'startYear' => $this->env['startyear'],
|
||||||
|
|||||||
@@ -193,7 +193,6 @@ class che_종전제의 extends Command\NationCommand{
|
|||||||
$nationList[] = $nationTarget;
|
$nationList[] = $nationTarget;
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'nationList' => $nationList,
|
'nationList' => $nationList,
|
||||||
'startYear' => $this->env['startyear'],
|
'startYear' => $this->env['startyear'],
|
||||||
|
|||||||
@@ -233,7 +233,6 @@ class che_천도 extends Command\NationCommand
|
|||||||
public function exportJSVars(): array
|
public function exportJSVars(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'cities' => \sammo\JSOptionsForCities(),
|
'cities' => \sammo\JSOptionsForCities(),
|
||||||
'distanceList' => new \stdClass(),
|
'distanceList' => new \stdClass(),
|
||||||
|
|||||||
@@ -199,7 +199,6 @@ class che_초토화 extends Command\NationCommand{
|
|||||||
public function exportJSVars(): array
|
public function exportJSVars(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'cities' => \sammo\JSOptionsForCities(),
|
'cities' => \sammo\JSOptionsForCities(),
|
||||||
'distanceList' => new \stdClass(),
|
'distanceList' => new \stdClass(),
|
||||||
|
|||||||
@@ -280,7 +280,6 @@ class che_피장파장 extends Command\NationCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'nationList' => $nationList,
|
'nationList' => $nationList,
|
||||||
'startYear' => $this->env['startyear'],
|
'startYear' => $this->env['startyear'],
|
||||||
|
|||||||
@@ -202,7 +202,6 @@ class che_허보 extends Command\NationCommand
|
|||||||
public function exportJSVars(): array
|
public function exportJSVars(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'mapTheme' => \sammo\getMapTheme(),
|
|
||||||
'procRes' => [
|
'procRes' => [
|
||||||
'cities' => \sammo\JSOptionsForCities(),
|
'cities' => \sammo\JSOptionsForCities(),
|
||||||
'distanceList' => new \stdClass(),
|
'distanceList' => new \stdClass(),
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ class DummyGeneral extends General{
|
|||||||
'dedication'=>0,
|
'dedication'=>0,
|
||||||
'gold'=>0,
|
'gold'=>0,
|
||||||
'rice'=>0,
|
'rice'=>0,
|
||||||
|
'leadership'=>10,
|
||||||
|
'strength'=>10,
|
||||||
|
'intel'=>10,
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->raw = $raw;
|
$this->raw = $raw;
|
||||||
|
|||||||
@@ -49,10 +49,20 @@ class FinishNationBetting extends \sammo\Event\Action
|
|||||||
}
|
}
|
||||||
|
|
||||||
$winnerTypes = [];
|
$winnerTypes = [];
|
||||||
|
|
||||||
|
$notInBettingWinner = 0;
|
||||||
foreach ($winnerNations as $winnerNationID) {
|
foreach ($winnerNations as $winnerNationID) {
|
||||||
$winnerTypes[] = $nationIDMap[$winnerNationID];
|
if(key_exists($winnerNationID, $nationIDMap)){
|
||||||
|
$winnerTypes[] = $nationIDMap[$winnerNationID];
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
//혹시라도 베팅 시점 이후에 생성된 국가라 없을 수 있다.
|
||||||
|
$winnerTypes[] = count($nationIDMap) + $notInBettingWinner;
|
||||||
|
$notInBettingWinner += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$winnerTypes = $bettingHelper->purifyBettingKey($winnerTypes);
|
|
||||||
|
$winnerTypes = $bettingHelper->purifyBettingKey($winnerTypes, $notInBettingWinner > 0);
|
||||||
|
|
||||||
$bettingHelper->giveReward($winnerTypes);
|
$bettingHelper->giveReward($winnerTypes);
|
||||||
$logger = new ActionLogger(0, 0, $env['year'], $env['month']);
|
$logger = new ActionLogger(0, 0, $env['year'], $env['month']);
|
||||||
|
|||||||
+17
-17
@@ -275,9 +275,17 @@ class GameConstBase
|
|||||||
|
|
||||||
/** @var array 선택 가능한 커맨드 */
|
/** @var array 선택 가능한 커맨드 */
|
||||||
public static $availableGeneralCommand = [
|
public static $availableGeneralCommand = [
|
||||||
'' => [
|
'개인' => [
|
||||||
'휴식',
|
'휴식',
|
||||||
'che_요양'
|
'che_요양',
|
||||||
|
'che_단련',
|
||||||
|
'che_숙련전환',
|
||||||
|
'che_견문',
|
||||||
|
'che_은퇴',
|
||||||
|
'che_장비매매',
|
||||||
|
'che_군량매매',
|
||||||
|
'che_내정특기초기화',
|
||||||
|
'che_전투특기초기화',
|
||||||
],
|
],
|
||||||
'내정' => [
|
'내정' => [
|
||||||
'che_농지개간',
|
'che_농지개간',
|
||||||
@@ -291,43 +299,35 @@ class GameConstBase
|
|||||||
'che_물자조달',
|
'che_물자조달',
|
||||||
],
|
],
|
||||||
'군사' => [
|
'군사' => [
|
||||||
'che_소집해제',
|
|
||||||
'che_첩보',
|
|
||||||
'che_징병',
|
'che_징병',
|
||||||
'che_모병',
|
'che_모병',
|
||||||
'che_훈련',
|
'che_훈련',
|
||||||
'che_사기진작',
|
'che_사기진작',
|
||||||
'che_출병',
|
'che_출병',
|
||||||
|
'che_집합',
|
||||||
|
'che_소집해제',
|
||||||
|
'che_첩보',
|
||||||
],
|
],
|
||||||
'인사' => [
|
'인사' => [
|
||||||
'che_이동',
|
'che_이동',
|
||||||
'che_강행',
|
'che_강행',
|
||||||
'che_인재탐색',
|
'che_인재탐색',
|
||||||
'che_등용',
|
'che_등용',
|
||||||
'che_집합',
|
|
||||||
'che_귀환',
|
'che_귀환',
|
||||||
'che_임관',
|
'che_임관',
|
||||||
'che_랜덤임관',
|
'che_랜덤임관',
|
||||||
'che_장수대상임관',
|
'che_장수대상임관',
|
||||||
],
|
],
|
||||||
'계략' => [
|
'계략' => [
|
||||||
'che_화계',
|
|
||||||
'che_파괴',
|
|
||||||
'che_탈취',
|
|
||||||
'che_선동',
|
'che_선동',
|
||||||
|
'che_탈취',
|
||||||
|
'che_파괴',
|
||||||
|
'che_화계',
|
||||||
],
|
],
|
||||||
'개인' => [
|
'국가' => [
|
||||||
'che_내정특기초기화',
|
|
||||||
'che_전투특기초기화',
|
|
||||||
'che_단련',
|
|
||||||
'che_숙련전환',
|
|
||||||
'che_견문',
|
|
||||||
'che_장비매매',
|
|
||||||
'che_군량매매',
|
|
||||||
'che_증여',
|
'che_증여',
|
||||||
'che_헌납',
|
'che_헌납',
|
||||||
'che_하야',
|
'che_하야',
|
||||||
'che_은퇴',
|
|
||||||
'che_거병',
|
'che_거병',
|
||||||
'che_건국',
|
'che_건국',
|
||||||
'che_선양',
|
'che_선양',
|
||||||
|
|||||||
@@ -110,48 +110,48 @@ class GameUnitConstBase{
|
|||||||
|
|
||||||
[
|
[
|
||||||
1200, self::T_ARCHER, '궁병',
|
1200, self::T_ARCHER, '궁병',
|
||||||
100, 100, 7, 15, 0, 10, 10,
|
100, 100, 7, 10, 0, 10, 10,
|
||||||
0, null, null, 0,
|
0, null, null, 0,
|
||||||
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
||||||
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
||||||
['표준적인 궁병입니다.','궁병은 회피특화입니다.'],
|
['표준적인 궁병입니다.','궁병은 선제사격을 하는 병종입니다.'],
|
||||||
null, null
|
null, ['che_궁병선제사격']
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
1201, self::T_ARCHER, '궁기병',
|
1201, self::T_ARCHER, '궁기병',
|
||||||
100, 100, 8, 25, 0, 11, 12,
|
100, 100, 8, 20, 0, 11, 12,
|
||||||
1000, null, ['동이'], 0,
|
1000, null, ['동이'], 0,
|
||||||
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
||||||
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
||||||
['말을 타고 잘 피합니다.'],
|
['말을 타고 잘 피합니다.'],
|
||||||
null, null
|
null, ['che_궁병선제사격']
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
1202, self::T_ARCHER, '연노병',
|
1202, self::T_ARCHER, '연노병',
|
||||||
150, 100, 8, 15, 0, 12, 11,
|
150, 100, 8, 10, 0, 12, 11,
|
||||||
1000, null, ['서촉'], 0,
|
1000, null, ['서촉'], 0,
|
||||||
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
||||||
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
||||||
['화살을 연사합니다.'],
|
['화살을 연사합니다.'],
|
||||||
null, null
|
null, ['che_궁병선제사격']
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
1203, self::T_ARCHER, '강궁병',
|
1203, self::T_ARCHER, '강궁병',
|
||||||
150, 150, 7, 15, 0, 13, 13,
|
150, 150, 7, 10, 0, 13, 13,
|
||||||
3000, ['양양'], null, 0,
|
3000, ['양양'], null, 0,
|
||||||
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
||||||
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
||||||
['강건한 궁병입니다.'],
|
['강건한 궁병입니다.'],
|
||||||
null, null
|
null, ['che_궁병선제사격']
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
1204, self::T_ARCHER, '석궁병',
|
1204, self::T_ARCHER, '석궁병',
|
||||||
200, 100, 7, 15, 0, 13, 13,
|
200, 100, 7, 10, 0, 13, 13,
|
||||||
3000, ['건업'], null, 0,
|
3000, ['건업'], null, 0,
|
||||||
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
||||||
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
||||||
['강력한 화살을 쏩니다.'],
|
['강력한 화살을 쏩니다.'],
|
||||||
null, null
|
null, ['che_궁병선제사격']
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -4095,17 +4095,21 @@ class GeneralAI
|
|||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$nationGenerals = $this->nationGenerals;
|
||||||
|
$nationGenerals[] = $this->general;
|
||||||
|
|
||||||
$dedicationList = array_map(function (General $general) {
|
$dedicationList = array_map(function (General $general) {
|
||||||
return $general->getRaw();
|
return $general->getRaw();
|
||||||
}, array_filter($this->nationGenerals, function (General $rawGeneral) {
|
}, array_filter($this->nationGenerals, function (General $rawGeneral) {
|
||||||
return $rawGeneral->getVar('officer_level') != 5;
|
return $rawGeneral->getVar('npc') != 5;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
$goldIncome = getGoldIncome($nation['nation'], $nation['level'], $nation['rate'], $nation['capital'], $nation['type'], $cityList);
|
$goldIncome = getGoldIncome($nation['nation'], $nation['level'], $nation['rate'], $nation['capital'], $nation['type'], $cityList);
|
||||||
$warIncome = getWarGoldIncome($nation['type'], $cityList);
|
$warIncome = getWarGoldIncome($nation['type'], $cityList);
|
||||||
$income = $goldIncome + $warIncome;
|
$income = $goldIncome + $warIncome;
|
||||||
|
|
||||||
$outcome = getOutcome(100, $dedicationList);
|
$outcome = Util::valueFit(getOutcome(100, $dedicationList), 1);
|
||||||
|
|
||||||
$bill = intval($income / $outcome * 90); // 수입의 90% 만 지급
|
$bill = intval($income / $outcome * 90); // 수입의 90% 만 지급
|
||||||
if ($nation['gold'] + $income - $outcome > $this->nationPolicy->reqNationGold * 2) {
|
if ($nation['gold'] + $income - $outcome > $this->nationPolicy->reqNationGold * 2) {
|
||||||
@@ -4138,6 +4142,9 @@ class GeneralAI
|
|||||||
return 20;
|
return 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$nationGenerals = $this->nationGenerals;
|
||||||
|
$nationGenerals[] = $this->general;
|
||||||
|
|
||||||
$dedicationList = array_map(function (General $general) {
|
$dedicationList = array_map(function (General $general) {
|
||||||
return $general->getRaw();
|
return $general->getRaw();
|
||||||
}, array_filter($this->nationGenerals, function (General $rawGeneral) {
|
}, array_filter($this->nationGenerals, function (General $rawGeneral) {
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ class ResetHelper{
|
|||||||
'month'=> $month,
|
'month'=> $month,
|
||||||
'init_year'=> $year,
|
'init_year'=> $year,
|
||||||
'init_month'=>$month,
|
'init_month'=>$month,
|
||||||
'map_theme' => $scenarioObj->getMapTheme(),
|
'map_theme' => $scenarioObj->getMapTheme(), //@deprecated
|
||||||
'season'=>$seasonIdx,
|
'season'=>$seasonIdx,
|
||||||
'msg'=>'공지사항',//TODO:공지사항
|
'msg'=>'공지사항',//TODO:공지사항
|
||||||
'maxgeneral'=>GameConst::$defaultMaxGeneral,
|
'maxgeneral'=>GameConst::$defaultMaxGeneral,
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ class TriggerOfficerLevel implements iAction{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,4 +58,30 @@ class TriggerOfficerLevel implements iAction{
|
|||||||
}
|
}
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getWarPowerMultiplier(WarUnit $unit): array
|
||||||
|
{
|
||||||
|
$officerLevel = $this->officerLevel;
|
||||||
|
$warPowerMultiply = 1;
|
||||||
|
$opposeWarPowerMultiply = 1;
|
||||||
|
if ($officerLevel == 12) {
|
||||||
|
$warPowerMultiply = 1.07;
|
||||||
|
$opposeWarPowerMultiply = 0.93;
|
||||||
|
}
|
||||||
|
else if($officerLevel == 11){
|
||||||
|
$warPowerMultiply = 1.05;
|
||||||
|
$opposeWarPowerMultiply = 0.95;
|
||||||
|
}
|
||||||
|
else if(in_array($officerLevel, [10, 8, 6])){
|
||||||
|
$warPowerMultiply = 1.10;
|
||||||
|
}
|
||||||
|
else if(in_array($officerLevel, [9, 7, 5])){
|
||||||
|
$opposeWarPowerMultiply = 0.90;
|
||||||
|
}
|
||||||
|
else if(in_array($officerLevel, [4, 3, 2])){
|
||||||
|
$warPowerMultiply = 1.05;
|
||||||
|
$opposeWarPowerMultiply = 0.95;
|
||||||
|
}
|
||||||
|
return [$warPowerMultiply, $opposeWarPowerMultiply];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+157
-88
@@ -1,7 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace sammo;
|
namespace sammo;
|
||||||
|
|
||||||
class WarUnit{
|
class WarUnit
|
||||||
|
{
|
||||||
|
|
||||||
protected $general;
|
protected $general;
|
||||||
protected $rawNation;
|
protected $rawNation;
|
||||||
@@ -31,32 +33,39 @@ class WarUnit{
|
|||||||
protected $logActivatedSkill = [];
|
protected $logActivatedSkill = [];
|
||||||
protected $isFinished = false;
|
protected $isFinished = false;
|
||||||
|
|
||||||
private function __construct(General $general){
|
private function __construct(General $general)
|
||||||
|
{
|
||||||
$this->general = $general;
|
$this->general = $general;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX:Dirty wrapper */
|
/* XXX:Dirty wrapper */
|
||||||
function getRaw():array{
|
function getRaw(): array
|
||||||
|
{
|
||||||
return $this->general->getRaw();
|
return $this->general->getRaw();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVar(string $key){
|
function getVar(string $key)
|
||||||
|
{
|
||||||
return $this->general->getVar($key);
|
return $this->general->getVar($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
function touchVar(string $key):bool{
|
function touchVar(string $key): bool
|
||||||
|
{
|
||||||
return $this->general->touchVar($key);
|
return $this->general->touchVar($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setVar(string $key, $value){
|
function setVar(string $key, $value)
|
||||||
|
{
|
||||||
return $this->general->setVar($key, $value);
|
return $this->general->setVar($key, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateVar(string $key, $value){
|
function updateVar(string $key, $value)
|
||||||
|
{
|
||||||
return $this->general->updateVar($key, $value);
|
return $this->general->updateVar($key, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateVarWithLimit(string $key, $value, $min = null, $max = null){
|
function updateVarWithLimit(string $key, $value, $min = null, $max = null)
|
||||||
|
{
|
||||||
return $this->general->updateVarWithLimit($key, $value, $min, $max);
|
return $this->general->updateVarWithLimit($key, $value, $min, $max);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +74,8 @@ class WarUnit{
|
|||||||
return $this->general->increaseVar($key, $value);
|
return $this->general->increaseVar($key, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function increaseVarWithLimit(string $key, $value, $min = null, $max = null){
|
function increaseVarWithLimit(string $key, $value, $min = null, $max = null)
|
||||||
|
{
|
||||||
return $this->general->increaseVarWithLimit($key, $value, $min, $max);
|
return $this->general->increaseVarWithLimit($key, $value, $min, $max);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,170 +84,203 @@ class WarUnit{
|
|||||||
return $this->general->multiplyVar($key, $value);
|
return $this->general->multiplyVar($key, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function multiplyVarWithLimit(string $key, $value, $min = null, $max = null){
|
function multiplyVarWithLimit(string $key, $value, $min = null, $max = null)
|
||||||
|
{
|
||||||
return $this->general->multiplyVarWithLimit($key, $value, $min, $max);
|
return $this->general->multiplyVarWithLimit($key, $value, $min, $max);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUpdatedValues():array {
|
function getUpdatedValues(): array
|
||||||
|
{
|
||||||
return $this->general->getUpdatedValues();
|
return $this->general->getUpdatedValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
function flushUpdateValues():void {
|
function flushUpdateValues(): void
|
||||||
|
{
|
||||||
$this->general->flushUpdateValues();
|
$this->general->flushUpdateValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function clearActivatedSkill(){
|
protected function clearActivatedSkill()
|
||||||
foreach($this->activatedSkill as $skillName=>$state){
|
{
|
||||||
if(!$state){
|
foreach ($this->activatedSkill as $skillName => $state) {
|
||||||
|
if (!$state) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!key_exists($skillName, $this->logActivatedSkill)){
|
if (!key_exists($skillName, $this->logActivatedSkill)) {
|
||||||
$this->logActivatedSkill[$skillName] = 1;
|
$this->logActivatedSkill[$skillName] = 1;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
$this->logActivatedSkill[$skillName] += 1;
|
$this->logActivatedSkill[$skillName] += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->activatedSkill = [];
|
$this->activatedSkill = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActivatedSkillLog():array{
|
function getActivatedSkillLog(): array
|
||||||
|
{
|
||||||
return $this->logActivatedSkill;
|
return $this->logActivatedSkill;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRawNation():array{
|
function getRawNation(): array
|
||||||
|
{
|
||||||
return $this->rawNation;
|
return $this->rawNation;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNationVar(string $key){
|
function getNationVar(string $key)
|
||||||
|
{
|
||||||
return $this->rawNation[$key];
|
return $this->rawNation[$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPhase():int{
|
function getPhase(): int
|
||||||
|
{
|
||||||
return $this->currPhase;
|
return $this->currPhase;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRealPhase():int{
|
function getRealPhase(): int
|
||||||
|
{
|
||||||
return $this->prePhase + $this->currPhase;
|
return $this->prePhase + $this->currPhase;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getName():string{
|
function getName(): string
|
||||||
|
{
|
||||||
return 'EMPTY';
|
return 'EMPTY';
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAttacker():bool{
|
function isAttacker(): bool
|
||||||
|
{
|
||||||
return $this->isAttacker;
|
return $this->isAttacker;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCrewType():GameUnitDetail{
|
function getCrewType(): GameUnitDetail
|
||||||
|
{
|
||||||
return $this->crewType;
|
return $this->crewType;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCrewTypeName():string{
|
function getCrewTypeName(): string
|
||||||
|
{
|
||||||
return $this->getCrewType()->name;
|
return $this->getCrewType()->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCrewTypeShortName():string{
|
function getCrewTypeShortName(): string
|
||||||
|
{
|
||||||
return $this->getCrewType()->getShortName();
|
return $this->getCrewType()->getShortName();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLogger():ActionLogger{
|
function getLogger(): ActionLogger
|
||||||
|
{
|
||||||
$logger = $this->getGeneral()->getLogger();
|
$logger = $this->getGeneral()->getLogger();
|
||||||
if($logger === null){
|
if ($logger === null) {
|
||||||
throw new \RuntimeException();
|
throw new \RuntimeException();
|
||||||
}
|
}
|
||||||
return $logger;
|
return $logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getKilled():int{
|
function getKilled(): int
|
||||||
|
{
|
||||||
return $this->killed;
|
return $this->killed;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDead():int{
|
function getDead(): int
|
||||||
|
{
|
||||||
return $this->dead;
|
return $this->dead;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getKilledCurrentBattle():int{
|
function getKilledCurrentBattle(): int
|
||||||
|
{
|
||||||
return $this->killedCurr;
|
return $this->killedCurr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDeadCurrentBattle():int{
|
function getDeadCurrentBattle(): int
|
||||||
|
{
|
||||||
return $this->deadCurr;
|
return $this->deadCurr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGeneral():General{
|
function getGeneral(): General
|
||||||
|
{
|
||||||
return $this->general;
|
return $this->general;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMaxPhase():int{
|
function getMaxPhase(): int
|
||||||
|
{
|
||||||
$phase = $this->getCrewType()->speed;
|
$phase = $this->getCrewType()->speed;
|
||||||
return $phase + $this->bonusPhase;
|
return $phase + $this->bonusPhase;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPrePhase(int $phase){
|
function setPrePhase(int $phase)
|
||||||
|
{
|
||||||
$this->prePhase = $phase;
|
$this->prePhase = $phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPhase(){
|
function addPhase(int $phase = 1)
|
||||||
$this->currPhase += 1;
|
{
|
||||||
|
$this->currPhase += $phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addBonusPhase(int $cnt){
|
function addBonusPhase(int $cnt)
|
||||||
|
{
|
||||||
$this->bonusPhase += $cnt;
|
$this->bonusPhase += $cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setOppose(?WarUnit $oppose){
|
function setOppose(?WarUnit $oppose)
|
||||||
|
{
|
||||||
$this->oppose = $oppose;
|
$this->oppose = $oppose;
|
||||||
$this->killedCurr = 0;
|
$this->killedCurr = 0;
|
||||||
$this->deadCurr = 0;
|
$this->deadCurr = 0;
|
||||||
$this->clearActivatedSkill();
|
$this->clearActivatedSkill();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOppose():?WarUnit{
|
function getOppose(): ?WarUnit
|
||||||
|
{
|
||||||
return $this->oppose;
|
return $this->oppose;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWarPower(){
|
function getWarPower()
|
||||||
|
{
|
||||||
return $this->warPower * $this->warPowerMultiply;
|
return $this->warPower * $this->warPowerMultiply;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRawWarPower(){
|
function getRawWarPower()
|
||||||
|
{
|
||||||
return $this->warPower;
|
return $this->warPower;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWarPowerMultiply(){
|
function getWarPowerMultiply()
|
||||||
|
{
|
||||||
return $this->warPowerMultiply;
|
return $this->warPowerMultiply;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setWarPowerMultiply($multiply = 1.0){
|
function setWarPowerMultiply($multiply = 1.0)
|
||||||
|
{
|
||||||
$this->warPowerMultiply = $multiply;
|
$this->warPowerMultiply = $multiply;
|
||||||
}
|
}
|
||||||
|
|
||||||
function multiplyWarPowerMultiply($multiply){
|
function multiplyWarPowerMultiply($multiply)
|
||||||
|
{
|
||||||
$this->warPowerMultiply *= $multiply;
|
$this->warPowerMultiply *= $multiply;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComputedAttack(){
|
function getComputedAttack()
|
||||||
|
{
|
||||||
return $this->getCrewType()->getComputedAttack($this->general, $this->getNationVar('tech'));
|
return $this->getCrewType()->getComputedAttack($this->general, $this->getNationVar('tech'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComputedDefence(){
|
function getComputedDefence()
|
||||||
|
{
|
||||||
return $this->getCrewType()->getComputedDefence($this->general, $this->getNationVar('tech'));
|
return $this->getCrewType()->getComputedDefence($this->general, $this->getNationVar('tech'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function computeWarPower(){
|
function computeWarPower()
|
||||||
|
{
|
||||||
$oppose = $this->getOppose();
|
$oppose = $this->getOppose();
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
$opposeGeneral = $oppose->getGeneral();
|
$opposeGeneral = $oppose->getGeneral();
|
||||||
|
|
||||||
$myAtt = $this->getComputedAttack();
|
$myAtt = $this->getComputedAttack();
|
||||||
$opDef = $oppose->getComputedDefence();
|
$opDef = $oppose->getComputedDefence();
|
||||||
// 감소할 병사
|
// 감소할 병사
|
||||||
$warPower = GameConst::$armperphase + $myAtt - $opDef;
|
$warPower = GameConst::$armperphase + $myAtt - $opDef;
|
||||||
$opposeWarPowerMultiply = 1.0;
|
$opposeWarPowerMultiply = 1.0;
|
||||||
|
|
||||||
if($warPower < 100){
|
if ($warPower < 100) {
|
||||||
//최소 전투력 50 보장
|
//최소 전투력 50 보장
|
||||||
$warPower = max(0, $warPower);
|
$warPower = max(0, $warPower);
|
||||||
$warPower = ($warPower + 100) / 2;
|
$warPower = ($warPower + 100) / 2;
|
||||||
@@ -248,11 +291,11 @@ class WarUnit{
|
|||||||
$warPower /= $oppose->getComputedTrain();
|
$warPower /= $oppose->getComputedTrain();
|
||||||
|
|
||||||
$genDexAtt = $this->getDex($this->getCrewType(), true);
|
$genDexAtt = $this->getDex($this->getCrewType(), true);
|
||||||
|
|
||||||
$oppDexDef = $oppose->getDex($this->getCrewType(), false);
|
$oppDexDef = $oppose->getDex($this->getCrewType(), false);
|
||||||
|
|
||||||
$warPower *= getDexLog($genDexAtt, $oppDexDef);
|
$warPower *= getDexLog($genDexAtt, $oppDexDef);
|
||||||
|
|
||||||
$warPower *= $this->getCrewType()->getAttackCoef($oppose->getCrewType());
|
$warPower *= $this->getCrewType()->getAttackCoef($oppose->getCrewType());
|
||||||
$opposeWarPowerMultiply *= $this->getCrewType()->getDefenceCoef($oppose->getCrewType());
|
$opposeWarPowerMultiply *= $this->getCrewType()->getDefenceCoef($oppose->getCrewType());
|
||||||
|
|
||||||
@@ -262,117 +305,143 @@ class WarUnit{
|
|||||||
return [$warPower, $opposeWarPowerMultiply];
|
return [$warPower, $opposeWarPowerMultiply];
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTrain(int $train){
|
function addTrain(int $train)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addAtmos(int $atmos){
|
function addAtmos(int $atmos)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTrainBonus(int $trainBonus){
|
function addTrainBonus(int $trainBonus)
|
||||||
|
{
|
||||||
$this->trainBonus += $trainBonus;
|
$this->trainBonus += $trainBonus;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addAtmosBonus(int $atmosBonus){
|
function addAtmosBonus(int $atmosBonus)
|
||||||
|
{
|
||||||
$this->atmosBonus += $atmosBonus;
|
$this->atmosBonus += $atmosBonus;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComputedTrain(){
|
function getComputedTrain()
|
||||||
|
{
|
||||||
return GameConst::$maxTrainByCommand;
|
return GameConst::$maxTrainByCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComputedAtmos(){
|
function getComputedAtmos()
|
||||||
|
{
|
||||||
return GameConst::$maxAtmosByCommand;
|
return GameConst::$maxAtmosByCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComputedCriticalRatio():float{
|
function getComputedCriticalRatio(): float
|
||||||
|
{
|
||||||
return $this->getCrewType()->getCriticalRatio($this->general);
|
return $this->getCrewType()->getCriticalRatio($this->general);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComputedAvoidRatio():float{
|
function getComputedAvoidRatio(): float
|
||||||
|
{
|
||||||
return $this->getCrewType()->avoid / 100;
|
return $this->getCrewType()->avoid / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addWin(){
|
function addWin()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
function addLose(){
|
function addLose()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDex(GameUnitDetail $crewType){
|
function getDex(GameUnitDetail $crewType)
|
||||||
|
{
|
||||||
throw new NotInheritedMethodException();
|
throw new NotInheritedMethodException();
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishBattle(){
|
function finishBattle()
|
||||||
|
{
|
||||||
throw new NotInheritedMethodException();
|
throw new NotInheritedMethodException();
|
||||||
}
|
}
|
||||||
|
|
||||||
function beginPhase():void{
|
function beginPhase(): void
|
||||||
|
{
|
||||||
$this->clearActivatedSkill();
|
$this->clearActivatedSkill();
|
||||||
$this->computeWarPower();
|
$this->computeWarPower();
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasActivatedSkill(string $skillName):bool{
|
function hasActivatedSkill(string $skillName): bool
|
||||||
return $this->activatedSkill[$skillName]??false;
|
{
|
||||||
|
return $this->activatedSkill[$skillName] ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasActivatedSkillOnLog(string $skillName):int{
|
function hasActivatedSkillOnLog(string $skillName): int
|
||||||
return ($this->logActivatedSkill[$skillName]??0)+($this->hasActivatedSkill($skillName)?1:0);
|
{
|
||||||
|
return ($this->logActivatedSkill[$skillName] ?? 0) + ($this->hasActivatedSkill($skillName) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function activateSkill(... $skillNames){
|
function activateSkill(...$skillNames)
|
||||||
foreach($skillNames as $skillName){
|
{
|
||||||
|
foreach ($skillNames as $skillName) {
|
||||||
$this->activatedSkill[$skillName] = true;
|
$this->activatedSkill[$skillName] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function deactivateSkill(... $skillNames){
|
function deactivateSkill(...$skillNames)
|
||||||
foreach($skillNames as $skillName){
|
{
|
||||||
|
foreach ($skillNames as $skillName) {
|
||||||
$this->activatedSkill[$skillName] = false;
|
$this->activatedSkill[$skillName] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHP():int{
|
function getHP(): int
|
||||||
|
{
|
||||||
throw new NotInheritedMethodException();
|
throw new NotInheritedMethodException();
|
||||||
}
|
}
|
||||||
|
|
||||||
function decreaseHP(int $damage):int{
|
function decreaseHP(int $damage): int
|
||||||
|
{
|
||||||
$this->dead += $damage;
|
$this->dead += $damage;
|
||||||
throw new NotInheritedMethodException();
|
throw new NotInheritedMethodException();
|
||||||
}
|
}
|
||||||
|
|
||||||
function increaseKilled(int $damage):int{
|
function increaseKilled(int $damage): int
|
||||||
|
{
|
||||||
$this->killed += $damage;
|
$this->killed += $damage;
|
||||||
throw new NotInheritedMethodException();
|
throw new NotInheritedMethodException();
|
||||||
}
|
}
|
||||||
|
|
||||||
function calcDamage():int{
|
function calcDamage(): int
|
||||||
|
{
|
||||||
$warPower = $this->getWarPower();
|
$warPower = $this->getWarPower();
|
||||||
$warPower *= Util::randRange(0.9, 1.1);
|
$warPower *= Util::randRange(0.9, 1.1);
|
||||||
return Util::round($warPower);
|
return Util::round($warPower);
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryWound():bool{
|
function tryWound(): bool
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function continueWar(&$noRice):bool{
|
function continueWar(&$noRice): bool
|
||||||
|
{
|
||||||
//전투가 가능하면 true
|
//전투가 가능하면 true
|
||||||
$noRice = false;
|
$noRice = false;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function logBattleResult(){
|
function logBattleResult()
|
||||||
|
{
|
||||||
$this->getLogger()->pushBattleResultTemplate($this, $this->getOppose());
|
$this->getLogger()->pushBattleResultTemplate($this, $this->getOppose());
|
||||||
}
|
}
|
||||||
|
|
||||||
function criticalDamage():float{
|
function criticalDamage(): float
|
||||||
|
{
|
||||||
//전특, 병종에 따라 필살 데미지가 달라질지도 모르므로 static 함수는 아닌 것으로
|
//전특, 병종에 따라 필살 데미지가 달라질지도 모르므로 static 함수는 아닌 것으로
|
||||||
return Util::randRange(1.3, 2.0);
|
return Util::randRange(1.3, 2.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyDB(\MeekroDB $db):bool{
|
function applyDB(\MeekroDB $db): bool
|
||||||
|
{
|
||||||
throw new MustNotBeReachedException('Must be WarUnitCity or WarUnitGeneral');
|
throw new MustNotBeReachedException('Must be WarUnitCity or WarUnitGeneral');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,25 +209,6 @@ class WarUnitGeneral extends WarUnit
|
|||||||
[$warPower, $opposeWarPowerMultiply] = parent::computeWarPower();
|
[$warPower, $opposeWarPowerMultiply] = parent::computeWarPower();
|
||||||
|
|
||||||
$general = $this->general;
|
$general = $this->general;
|
||||||
$cityID = $general->getCityID();
|
|
||||||
$officerLevel = $general->getVar('officer_level');
|
|
||||||
$officerCity = $general->getVar('officer_city');
|
|
||||||
|
|
||||||
if ($this->isAttacker) {
|
|
||||||
if ($officerLevel == 12) {
|
|
||||||
$warPower *= 1.10;
|
|
||||||
} else if ($officerLevel == 11 || $officerLevel == 10 || $officerLevel == 8 || $officerLevel == 6) {
|
|
||||||
$warPower *= 1.05;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ($officerLevel == 12) {
|
|
||||||
$opposeWarPowerMultiply *= 0.90;
|
|
||||||
} else if ($officerLevel == 11 || $officerLevel == 9 || $officerLevel == 7 || $officerLevel == 5) {
|
|
||||||
$opposeWarPowerMultiply *= 0.95;
|
|
||||||
} else if (2 <= $officerLevel && $officerLevel <= 4 && $officerCity == $cityID) {
|
|
||||||
$opposeWarPowerMultiply *= 0.95;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$expLevel = $general->getVar('explevel');
|
$expLevel = $general->getVar('explevel');
|
||||||
|
|
||||||
@@ -238,7 +219,6 @@ class WarUnitGeneral extends WarUnit
|
|||||||
$opposeWarPowerMultiply *= max(0.01, 1 - $expLevel / 300);
|
$opposeWarPowerMultiply *= max(0.01, 1 - $expLevel / 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[$specialMyWarPowerMultiply, $specialOpposeWarPowerMultiply] = $this->general->getWarPowerMultiplier($this);
|
[$specialMyWarPowerMultiply, $specialOpposeWarPowerMultiply] = $this->general->getWarPowerMultiplier($this);
|
||||||
$warPower *= $specialMyWarPowerMultiply;
|
$warPower *= $specialMyWarPowerMultiply;
|
||||||
$opposeWarPowerMultiply *= $specialOpposeWarPowerMultiply;
|
$opposeWarPowerMultiply *= $specialOpposeWarPowerMultiply;
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\WarUnitTrigger;
|
||||||
|
|
||||||
|
use sammo\ActionLogger;
|
||||||
|
use sammo\BaseWarUnitTrigger;
|
||||||
|
use sammo\GameUnitConst;
|
||||||
|
use sammo\WarUnitGeneral;
|
||||||
|
use sammo\WarUnitCity;
|
||||||
|
use sammo\WarUnit;
|
||||||
|
use sammo\GameUnitDetail;
|
||||||
|
use sammo\Util;
|
||||||
|
use sammo\ObjectTrigger;
|
||||||
|
|
||||||
|
class che_궁병선제사격 extends BaseWarUnitTrigger
|
||||||
|
{
|
||||||
|
protected $priority = ObjectTrigger::PRIORITY_BEGIN;
|
||||||
|
|
||||||
|
protected function actionWar(WarUnit $self, WarUnit $oppose, array &$selfEnv, array &$opposeEnv): bool
|
||||||
|
{
|
||||||
|
assert($self instanceof WarUnitGeneral, 'General만 발동 가능');
|
||||||
|
if ($self->getPhase() !== 0 && $oppose->getPhase() !== 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($self->hasActivatedSkill('선제')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ($self->hasActivatedSkillOnLog('선제')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->activateSkill('특수', '선제');
|
||||||
|
if (!$self->isAttacker()) {
|
||||||
|
$self->addPhase(-1);
|
||||||
|
$oppose->addPhase(-1);
|
||||||
|
if ($oppose->getCrewType()->armType == GameUnitConst::T_ARCHER) {
|
||||||
|
$oppose->multiplyWarPowerMultiply(0.5);
|
||||||
|
} else {
|
||||||
|
$oppose->multiplyWarPowerMultiply(0);
|
||||||
|
$self->activateSkill('회피불가', '필살불가', '계략불가');
|
||||||
|
$oppose->activateSkill('회피불가', '계략불가');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$oppose->multiplyWarPowerMultiply(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
$oppose->getLogger()->pushGeneralBattleDetailLog('상대에게 <R>선제 사격</>을 받았다!</>', ActionLogger::PLAIN);
|
||||||
|
$self->getLogger()->pushGeneralBattleDetailLog('상대에게 <C>선제 사격</>을 했다!</>', ActionLogger::PLAIN);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,11 +20,14 @@ class che_돌격지속 extends BaseWarUnitTrigger{
|
|||||||
if(!$self->isAttacker()){
|
if(!$self->isAttacker()){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if($self->getPhase() < $self->getMaxPhase() - 1){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
$attackCoef = $self->getCrewType()->getAttackCoef($oppose->getCrewType());
|
$attackCoef = $self->getCrewType()->getAttackCoef($oppose->getCrewType());
|
||||||
if($attackCoef < 1){
|
if($attackCoef < 1){
|
||||||
|
if($oppose->hasActivatedSkill('선제') && $self->getPhase() >= $self->getMaxPhase() - 2){
|
||||||
|
$self->addBonusPhase(-1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if($self->getPhase() < $self->getMaxPhase() - 1){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
$self->addBonusPhase(1);
|
$self->addBonusPhase(1);
|
||||||
|
|||||||
@@ -33,9 +33,6 @@ class che_약탈발동 extends BaseWarUnitTrigger
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$general->increaseVarWithLimit('atmos', $selfEnv['addAtmos'], 0, GameConst::$maxAtmosByWar);
|
|
||||||
|
|
||||||
$opposeGeneral = $oppose->getGeneral();
|
$opposeGeneral = $oppose->getGeneral();
|
||||||
|
|
||||||
$theftGold = $opposeGeneral->getVar('gold') * $selfEnv['theftRatio'];
|
$theftGold = $opposeGeneral->getVar('gold') * $selfEnv['theftRatio'];
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"title": "【가상모드24-b】 유저무쌍 멀티 유니버스!(천지비급)",
|
"title": "【가상모드24-b】 유저무쌍 멀티 유니버스!(비급)",
|
||||||
"startYear": 180,
|
"startYear": 180,
|
||||||
"history": [
|
"history": [
|
||||||
"<C>●</>180년 1월:<L><b>【가상모드24-b】</b>유저무쌍 멀티 유니버스!(비급)</>",
|
"<C>●</>180년 1월:<L><b>【가상모드24-b】</b>유저무쌍 멀티 유니버스!(비급)</>",
|
||||||
|
|||||||
@@ -0,0 +1,734 @@
|
|||||||
|
{
|
||||||
|
"title": "【가상모드25】 악질유저무쌍!",
|
||||||
|
"startYear": 180,
|
||||||
|
"history": [
|
||||||
|
"<C>●</>180년 1월:<L><b>【가상모드25】</b>악질유저무쌍!</>",
|
||||||
|
"<C>●</>180년 1월:<L><b>【이벤트】</b></>최고의 악질유저를 가려라!"
|
||||||
|
],
|
||||||
|
"stat": {
|
||||||
|
"total": 310,
|
||||||
|
"min": 40,
|
||||||
|
"max": 140
|
||||||
|
},
|
||||||
|
"iconPath": ".",
|
||||||
|
"fiction": 1,
|
||||||
|
"nation":[
|
||||||
|
|
||||||
|
],
|
||||||
|
"diplomacy":[],
|
||||||
|
"general":[
|
||||||
|
[0, "아회남", null, 0, null, 65, 74, 26, 0, 160, 300, null, null],
|
||||||
|
[0, "이적", null, 0, null, 40, 24, 84, 0, 160, 300, null, null],
|
||||||
|
[0, "윤상", null, 0, null, 51, 44, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "윤묵", null, 0, null, 26, 15, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "우금", null, 0, null, 85, 82, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "위관", null, 0, null, 69, 46, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "원윤", null, 0, null, 32, 14, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "원희", null, 0, null, 66, 43, 63, 0, 160, 300, null, null],
|
||||||
|
[0, "염행", null, 0, null, 78, 90, 58, 0, 160, 300, null, null],
|
||||||
|
[0, "염유", null, 0, null, 71, 50, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "원술", null, 0, null, 76, 55, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "원상", null, 0, null, 63, 75, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "원소", null, 0, null, 90, 62, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "염상", null, 0, null, 40, 27, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "원담", null, 0, null, 60, 78, 30, 0, 160, 300, null, null],
|
||||||
|
[0, "염포", null, 0, null, 40, 25, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "왕위", null, 0, null, 60, 70, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "왕윤", null, 0, null, 26, 6, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "왕항", null, 0, null, 76, 43, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "왕찬", null, 0, null, 15, 3, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "왕수", null, 0, null, 54, 27, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "왕숙", null, 0, null, 36, 22, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "왕준", null, 0, null, 85, 64, 84, 0, 160, 300, null, null],
|
||||||
|
[0, "왕쌍", null, 0, null, 67, 88, 19, 0, 160, 300, null, null],
|
||||||
|
[0, "왕창", null, 0, null, 74, 57, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "왕평", null, 0, null, 88, 81, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "왕보", null, 0, null, 62, 41, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "왕문", null, 0, null, 65, 64, 31, 0, 160, 300, null, null],
|
||||||
|
[0, "왕릉", null, 0, null, 74, 50, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "왕루", null, 0, null, 28, 30, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "왕랑", null, 0, null, 47, 35, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "온회", null, 0, null, 62, 36, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "하안", null, 0, null, 15, 30, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "괴월", null, 0, null, 50, 38, 85, 0, 160, 300, null, null],
|
||||||
|
[0, "괴량", null, 0, null, 68, 33, 88, 0, 160, 300, null, null],
|
||||||
|
[0, "가화", null, 0, null, 49, 65, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "가규", null, 0, null, 78, 61, 84, 0, 160, 300, null, null],
|
||||||
|
[0, "하의", null, 0, null, 56, 69, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "화흠", null, 0, null, 51, 33, 88, 0, 160, 300, null, null],
|
||||||
|
[0, "가후", null, 0, null, 71, 40, 98, 0, 160, 300, null, null],
|
||||||
|
[0, "곽가", null, 0, null, 70, 41, 97, 0, 160, 300, null, null],
|
||||||
|
[0, "악환", null, 0, null, 65, 80, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "곽사", null, 0, null, 64, 76, 13, 0, 160, 300, null, null],
|
||||||
|
[0, "악취", null, 0, null, 53, 66, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "곽준", null, 0, null, 73, 52, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "학소", null, 0, null, 88, 63, 83, 0, 160, 300, null, null],
|
||||||
|
[0, "악진", null, 0, null, 80, 85, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "곽도", null, 0, null, 62, 50, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "학맹", null, 0, null, 62, 67, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "곽유지", null, 0, null, 28, 9, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "곽익", null, 0, null, 73, 69, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "곽회", null, 0, null, 90, 66, 85, 0, 160, 300, null, null],
|
||||||
|
[0, "하후위", null, 0, null, 71, 73, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "하후연", null, 0, null, 95, 92, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "하후은", null, 0, null, 63, 72, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "하후화", null, 0, null, 48, 51, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "하후혜", null, 0, null, 50, 44, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "하후현", null, 0, null, 54, 39, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "하후상", null, 0, null, 79, 55, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "하후덕", null, 0, null, 69, 73, 32, 0, 160, 300, null, null],
|
||||||
|
[0, "하후돈", null, 0, null, 91, 88, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "하후패", null, 0, null, 79, 85, 63, 0, 160, 300, null, null],
|
||||||
|
[0, "하후무", null, 0, null, 20, 7, 4, 0, 160, 300, null, null],
|
||||||
|
[0, "가충", null, 0, null, 54, 31, 89, 0, 160, 300, null, null],
|
||||||
|
[0, "하진", null, 0, null, 68, 54, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "화웅", null, 0, null, 78, 90, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "한윤", null, 0, null, 26, 29, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "관우", null, 0, null, 96, 99, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "환계", null, 0, null, 25, 26, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "관해", null, 0, null, 70, 82, 10, 0, 160, 300, null, null],
|
||||||
|
[0, "관구검", null, 0, null, 84, 86, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "한현", null, 0, null, 22, 33, 7, 0, 160, 300, null, null],
|
||||||
|
[0, "한호", null, 0, null, 73, 61, 84, 0, 160, 300, null, null],
|
||||||
|
[0, "관흥", null, 0, null, 76, 84, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "관색", null, 0, null, 74, 83, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "한수", null, 0, null, 78, 58, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "한숭", null, 0, null, 25, 15, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "관정", null, 0, null, 36, 52, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "한섬", null, 0, null, 69, 66, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "감택", null, 0, null, 51, 49, 83, 0, 160, 300, null, null],
|
||||||
|
[0, "한충", null, 0, null, 64, 67, 18, 0, 160, 300, null, null],
|
||||||
|
[0, "한당", null, 0, null, 76, 85, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "한덕", null, 0, null, 63, 76, 25, 0, 160, 300, null, null],
|
||||||
|
[0, "감녕", null, 0, null, 92, 95, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "한복", null, 0, null, 28, 3, 27, 0, 160, 300, null, null],
|
||||||
|
[0, "관평", null, 0, null, 78, 82, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "간옹", null, 0, null, 20, 32, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "안량", null, 0, null, 88, 96, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "위연", null, 0, null, 91, 90, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "국의", null, 0, null, 84, 78, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "희지재", null, 0, null, 63, 35, 91, 0, 160, 300, null, null],
|
||||||
|
[0, "위속", null, 0, null, 67, 78, 31, 0, 160, 300, null, null],
|
||||||
|
[0, "위유", null, 0, null, 46, 29, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "우금2", null, 0, null, 72, 79, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "우보", null, 0, null, 38, 60, 21, 0, 160, 300, null, null],
|
||||||
|
[0, "강유", null, 0, null, 92, 72, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "공지", null, 0, null, 43, 53, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "교유", null, 0, null, 64, 69, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "공도", null, 0, null, 59, 70, 23, 0, 160, 300, null, null],
|
||||||
|
[0, "허공", null, 0, null, 44, 66, 64, 0, 160, 300, null, null],
|
||||||
|
[0, "허정", null, 0, null, 23, 5, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "허저", null, 0, null, 74, 97, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "허유", null, 0, null, 36, 21, 80, 0, 160, 300, null, null],
|
||||||
|
[0, "기령", null, 0, null, 85, 84, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "김의", null, 0, null, 32, 38, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "김배삼결", null, 0, null, 64, 76, 19, 0, 160, 300, null, null],
|
||||||
|
[0, "김선", null, 0, null, 52, 68, 13, 0, 160, 300, null, null],
|
||||||
|
[0, "우번", null, 0, null, 46, 46, 87, 0, 160, 300, null, null],
|
||||||
|
[0, "형도영", null, 0, null, 69, 79, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "엄안", null, 0, null, 82, 83, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "엄망", null, 0, null, 68, 71, 40, 0, 160, 300, null, null],
|
||||||
|
[0, "엄준", null, 0, null, 41, 12, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "엄정", null, 0, null, 50, 55, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "엄백호", null, 0, null, 67, 70, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "엄여", null, 0, null, 61, 78, 44, 0, 160, 300, null, null],
|
||||||
|
[0, "오의", null, 0, null, 79, 73, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "황개", null, 0, null, 80, 86, 64, 0, 160, 300, null, null],
|
||||||
|
[0, "고간", null, 0, null, 74, 56, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "황권", null, 0, null, 75, 59, 88, 0, 160, 300, null, null],
|
||||||
|
[0, "고유", null, 0, null, 57, 43, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "고순", null, 0, null, 87, 89, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "고상", null, 0, null, 68, 68, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "고승", null, 0, null, 67, 73, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "후성", null, 0, null, 74, 75, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "후선", null, 0, null, 63, 66, 34, 0, 160, 300, null, null],
|
||||||
|
[0, "황조", null, 0, null, 81, 66, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "공손월", null, 0, null, 74, 72, 47, 0, 160, 300, null, null],
|
||||||
|
[0, "공손연", null, 0, null, 65, 70, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "공손공", null, 0, null, 39, 17, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "공손강", null, 0, null, 72, 66, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "공손찬", null, 0, null, 86, 82, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "공손속", null, 0, null, 63, 68, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "공손도", null, 0, null, 67, 71, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "공손범", null, 0, null, 73, 69, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "황충", null, 0, null, 88, 96, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "고정", null, 0, null, 55, 63, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "고패", null, 0, null, 66, 48, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "황보숭", null, 0, null, 91, 61, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "공융", null, 0, null, 30, 5, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "고람", null, 0, null, 76, 82, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "오경", null, 0, null, 69, 66, 45, 0, 160, 300, null, null],
|
||||||
|
[0, "호거아", null, 0, null, 70, 82, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "호진", null, 0, null, 65, 74, 12, 0, 160, 300, null, null],
|
||||||
|
[0, "올돌골", null, 0, null, 79, 86, 11, 0, 160, 300, null, null],
|
||||||
|
[0, "호반", null, 0, null, 55, 55, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "오반", null, 0, null, 74, 71, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "고옹", null, 0, null, 52, 18, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "오란", null, 0, null, 68, 80, 35, 0, 160, 300, null, null],
|
||||||
|
[0, "채화", null, 0, null, 39, 50, 1, 0, 160, 300, null, null],
|
||||||
|
[0, "채중", null, 0, null, 40, 54, 2, 0, 160, 300, null, null],
|
||||||
|
[0, "채모", null, 0, null, 70, 55, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "착융", null, 0, null, 60, 69, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "사마의", null, 0, null, 99, 63, 98, 0, 160, 300, null, null],
|
||||||
|
[0, "사마염", null, 0, null, 69, 59, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "사마사", null, 0, null, 84, 64, 89, 0, 160, 300, null, null],
|
||||||
|
[0, "사마소", null, 0, null, 85, 57, 88, 0, 160, 300, null, null],
|
||||||
|
[0, "사마부", null, 0, null, 70, 37, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "사마랑", null, 0, null, 20, 21, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "사마가", null, 0, null, 66, 84, 25, 0, 160, 300, null, null],
|
||||||
|
[0, "주흔", null, 0, null, 65, 51, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "주앙", null, 0, null, 74, 65, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "주지", null, 0, null, 73, 85, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "주창", null, 0, null, 68, 77, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "주태", null, 0, null, 84, 90, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "주방", null, 0, null, 52, 41, 80, 0, 160, 300, null, null],
|
||||||
|
[0, "주유", null, 0, null, 97, 71, 97, 0, 160, 300, null, null],
|
||||||
|
[0, "주환", null, 0, null, 87, 84, 64, 0, 160, 300, null, null],
|
||||||
|
[0, "주거", null, 0, null, 77, 57, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "축융", null, 0, null, 72, 75, 35, 0, 160, 300, null, null],
|
||||||
|
[0, "주준", null, 0, null, 89, 57, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "주연", null, 0, null, 86, 75, 57, 0, 160, 300, null, null],
|
||||||
|
[0, "주치", null, 0, null, 71, 56, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "주포", null, 0, null, 68, 73, 34, 0, 160, 300, null, null],
|
||||||
|
[0, "주령", null, 0, null, 78, 73, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "순욱", null, 0, null, 78, 38, 97, 0, 160, 300, null, null],
|
||||||
|
[0, "순우경", null, 0, null, 78, 66, 29, 0, 160, 300, null, null],
|
||||||
|
[0, "순심", null, 0, null, 45, 25, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "순유", null, 0, null, 80, 35, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "장완", null, 0, null, 78, 34, 89, 0, 160, 300, null, null],
|
||||||
|
[0, "종회", null, 0, null, 88, 62, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "장간", null, 0, null, 19, 6, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "장의거", null, 0, null, 71, 41, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "장흠", null, 0, null, 78, 85, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "장제3", null, 0, null, 62, 43, 85, 0, 160, 300, null, null],
|
||||||
|
[0, "초주", null, 0, null, 16, 3, 67, 0, 160, 300, null, null],
|
||||||
|
[0, "초촉", null, 0, null, 65, 76, 33, 0, 160, 300, null, null],
|
||||||
|
[0, "향총", null, 0, null, 76, 56, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "종요", null, 0, null, 79, 24, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "향랑", null, 0, null, 28, 18, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "서영", null, 0, null, 92, 80, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈각", null, 0, null, 72, 47, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈근", null, 0, null, 75, 34, 85, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈균", null, 0, null, 29, 25, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈탄", null, 0, null, 72, 54, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈량", null, 0, null, 98, 43, 100, 0, 160, 300, null, null],
|
||||||
|
[0, "서황", null, 0, null, 95, 94, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "서서", null, 0, null, 85, 64, 94, 0, 160, 300, null, null],
|
||||||
|
[0, "서성", null, 0, null, 86, 81, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "서막", null, 0, null, 55, 32, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "신의", null, 0, null, 55, 59, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "신탐", null, 0, null, 56, 62, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "심배", null, 0, null, 80, 60, 84, 0, 160, 300, null, null],
|
||||||
|
[0, "신비", null, 0, null, 42, 24, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "신평", null, 0, null, 69, 43, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "진복", null, 0, null, 31, 7, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "진랑", null, 0, null, 58, 70, 35, 0, 160, 300, null, null],
|
||||||
|
[0, "휴고", null, 0, null, 63, 71, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "추단", null, 0, null, 61, 64, 34, 0, 160, 300, null, null],
|
||||||
|
[0, "성의", null, 0, null, 74, 72, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "성공영", null, 0, null, 73, 58, 80, 0, 160, 300, null, null],
|
||||||
|
[0, "설종", null, 0, null, 34, 16, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "단경", null, 0, null, 71, 68, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "전종", null, 0, null, 78, 55, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "조예", null, 0, null, 72, 52, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "조휴", null, 0, null, 84, 78, 58, 0, 160, 300, null, null],
|
||||||
|
[0, "송헌", null, 0, null, 68, 77, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "조앙", null, 0, null, 78, 50, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "조홍", null, 0, null, 80, 75, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "조순", null, 0, null, 85, 83, 63, 0, 160, 300, null, null],
|
||||||
|
[0, "조창", null, 0, null, 86, 91, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "조식", null, 0, null, 45, 22, 86, 0, 160, 300, null, null],
|
||||||
|
[0, "조진", null, 0, null, 88, 74, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "조인", null, 0, null, 94, 90, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "조성", null, 0, null, 54, 74, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "조조", null, 0, null, 100, 72, 96, 0, 160, 300, null, null],
|
||||||
|
[0, "조충", null, 0, null, 43, 21, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "장패", null, 0, null, 78, 86, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "조비", null, 0, null, 75, 64, 87, 0, 160, 300, null, null],
|
||||||
|
[0, "조표", null, 0, null, 54, 69, 32, 0, 160, 300, null, null],
|
||||||
|
[0, "저수", null, 0, null, 86, 46, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "소비", null, 0, null, 69, 45, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "조무", null, 0, null, 70, 71, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "손환", null, 0, null, 82, 56, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "손견", null, 0, null, 94, 95, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "손건", null, 0, null, 44, 33, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "손권", null, 0, null, 86, 61, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "손교", null, 0, null, 77, 72, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "손책", null, 0, null, 93, 94, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "손소", null, 0, null, 82, 79, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "손정", null, 0, null, 66, 53, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "손중", null, 0, null, 62, 71, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "손등", null, 0, null, 62, 37, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "손유", null, 0, null, 77, 70, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "손익", null, 0, null, 67, 83, 27, 0, 160, 300, null, null],
|
||||||
|
[0, "손례", null, 0, null, 78, 81, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "태사자", null, 0, null, 94, 94, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "대래동주", null, 0, null, 51, 53, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "대릉", null, 0, null, 70, 75, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "타사대왕", null, 0, null, 62, 48, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "담웅", null, 0, null, 58, 73, 14, 0, 160, 300, null, null],
|
||||||
|
[0, "장윤", null, 0, null, 72, 67, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "조운", null, 0, null, 90, 96, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "장위", null, 0, null, 74, 66, 45, 0, 160, 300, null, null],
|
||||||
|
[0, "장영", null, 0, null, 75, 74, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "장연", null, 0, null, 76, 81, 57, 0, 160, 300, null, null],
|
||||||
|
[0, "장횡", null, 0, null, 59, 70, 23, 0, 160, 300, null, null],
|
||||||
|
[0, "장온", null, 0, null, 32, 10, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "장개", null, 0, null, 34, 66, 8, 0, 160, 300, null, null],
|
||||||
|
[0, "장각", null, 0, null, 87, 35, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "장기", null, 0, null, 74, 35, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "장의", null, 0, null, 79, 55, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "장훈", null, 0, null, 72, 68, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "장굉", null, 0, null, 24, 22, 86, 0, 160, 300, null, null],
|
||||||
|
[0, "장합", null, 0, null, 92, 89, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "조홍2", null, 0, null, 66, 72, 28, 0, 160, 300, null, null],
|
||||||
|
[0, "장제2", null, 0, null, 70, 66, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "장수", null, 0, null, 80, 73, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "장소", null, 0, null, 41, 13, 87, 0, 160, 300, null, null],
|
||||||
|
[0, "장송", null, 0, null, 40, 6, 85, 0, 160, 300, null, null],
|
||||||
|
[0, "장임", null, 0, null, 85, 84, 64, 0, 160, 300, null, null],
|
||||||
|
[0, "장제", null, 0, null, 67, 43, 80, 0, 160, 300, null, null],
|
||||||
|
[0, "장막", null, 0, null, 52, 53, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "조범", null, 0, null, 28, 21, 32, 0, 160, 300, null, null],
|
||||||
|
[0, "장비", null, 0, null, 87, 98, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "장포", null, 0, null, 78, 84, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "장보", null, 0, null, 83, 60, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "장만성", null, 0, null, 75, 81, 45, 0, 160, 300, null, null],
|
||||||
|
[0, "장양", null, 0, null, 72, 70, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "장익", null, 0, null, 75, 55, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "장료", null, 0, null, 96, 94, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "장량", null, 0, null, 78, 80, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "조루", null, 0, null, 70, 43, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "장로", null, 0, null, 65, 42, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "진횡", null, 0, null, 64, 63, 26, 0, 160, 300, null, null],
|
||||||
|
[0, "진응", null, 0, null, 62, 72, 45, 0, 160, 300, null, null],
|
||||||
|
[0, "진기", null, 0, null, 58, 65, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "진궁", null, 0, null, 84, 55, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "진교", null, 0, null, 61, 27, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "진군", null, 0, null, 32, 14, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "진규", null, 0, null, 30, 4, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "진식", null, 0, null, 70, 71, 25, 0, 160, 300, null, null],
|
||||||
|
[0, "진진", null, 0, null, 46, 46, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "진태", null, 0, null, 86, 68, 89, 0, 160, 300, null, null],
|
||||||
|
[0, "진등", null, 0, null, 79, 59, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "진도", null, 0, null, 82, 78, 58, 0, 160, 300, null, null],
|
||||||
|
[0, "진무", null, 0, null, 76, 87, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "진란", null, 0, null, 66, 69, 40, 0, 160, 300, null, null],
|
||||||
|
[0, "진림", null, 0, null, 25, 9, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "정욱", null, 0, null, 76, 49, 94, 0, 160, 300, null, null],
|
||||||
|
[0, "정원지", null, 0, null, 69, 74, 17, 0, 160, 300, null, null],
|
||||||
|
[0, "정은", null, 0, null, 69, 73, 40, 0, 160, 300, null, null],
|
||||||
|
[0, "정원", null, 0, null, 70, 76, 35, 0, 160, 300, null, null],
|
||||||
|
[0, "정보", null, 0, null, 84, 79, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "정봉", null, 0, null, 81, 92, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "전위", null, 0, null, 79, 98, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "전해", null, 0, null, 68, 65, 45, 0, 160, 300, null, null],
|
||||||
|
[0, "전주", null, 0, null, 66, 51, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "전풍", null, 0, null, 82, 43, 96, 0, 160, 300, null, null],
|
||||||
|
[0, "전예", null, 0, null, 93, 85, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "동윤", null, 0, null, 47, 28, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "동화", null, 0, null, 57, 34, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "등애", null, 0, null, 92, 73, 94, 0, 160, 300, null, null],
|
||||||
|
[0, "도겸", null, 0, null, 51, 27, 64, 0, 160, 300, null, null],
|
||||||
|
[0, "등현", null, 0, null, 61, 73, 45, 0, 160, 300, null, null],
|
||||||
|
[0, "등지", null, 0, null, 73, 52, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "동습", null, 0, null, 72, 85, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "동승", null, 0, null, 56, 53, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "동소", null, 0, null, 34, 25, 80, 0, 160, 300, null, null],
|
||||||
|
[0, "동탁", null, 0, null, 91, 87, 67, 0, 160, 300, null, null],
|
||||||
|
[0, "동도나", null, 0, null, 68, 73, 31, 0, 160, 300, null, null],
|
||||||
|
[0, "동민", null, 0, null, 49, 60, 25, 0, 160, 300, null, null],
|
||||||
|
[0, "등무", null, 0, null, 61, 75, 29, 0, 160, 300, null, null],
|
||||||
|
[0, "두기", null, 0, null, 74, 43, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "두예", null, 0, null, 96, 69, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "배원소", null, 0, null, 49, 65, 25, 0, 160, 300, null, null],
|
||||||
|
[0, "마완", null, 0, null, 71, 74, 16, 0, 160, 300, null, null],
|
||||||
|
[0, "마휴", null, 0, null, 68, 73, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "파재", null, 0, null, 74, 74, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "마준", null, 0, null, 38, 52, 31, 0, 160, 300, null, null],
|
||||||
|
[0, "마속", null, 0, null, 61, 59, 84, 0, 160, 300, null, null],
|
||||||
|
[0, "마대", null, 0, null, 79, 85, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "마충", null, 0, null, 78, 72, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "마초", null, 0, null, 86, 97, 44, 0, 160, 300, null, null],
|
||||||
|
[0, "마철", null, 0, null, 70, 62, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "마등", null, 0, null, 85, 80, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "마량", null, 0, null, 53, 23, 85, 0, 160, 300, null, null],
|
||||||
|
[0, "반준", null, 0, null, 61, 46, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "반장", null, 0, null, 76, 80, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "번조", null, 0, null, 66, 73, 31, 0, 160, 300, null, null],
|
||||||
|
[0, "번능", null, 0, null, 69, 61, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "반봉", null, 0, null, 56, 77, 4, 0, 160, 300, null, null],
|
||||||
|
[0, "비의", null, 0, null, 82, 56, 88, 0, 160, 300, null, null],
|
||||||
|
[0, "비연", null, 0, null, 60, 66, 21, 0, 160, 300, null, null],
|
||||||
|
[0, "비시", null, 0, null, 18, 28, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "미축", null, 0, null, 33, 29, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "미방", null, 0, null, 54, 61, 32, 0, 160, 300, null, null],
|
||||||
|
[0, "비요", null, 0, null, 70, 52, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "무안국", null, 0, null, 70, 79, 34, 0, 160, 300, null, null],
|
||||||
|
[0, "풍습", null, 0, null, 72, 71, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "부사인", null, 0, null, 46, 63, 37, 0, 160, 300, null, null],
|
||||||
|
[0, "부첨", null, 0, null, 73, 85, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "부손", null, 0, null, 29, 13, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "문앙", null, 0, null, 76, 96, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "문흠", null, 0, null, 74, 79, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "문추", null, 0, null, 87, 95, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "문빙", null, 0, null, 88, 85, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "변희", null, 0, null, 56, 70, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "망아장", null, 0, null, 45, 79, 3, 0, 160, 300, null, null],
|
||||||
|
[0, "봉기", null, 0, null, 56, 48, 84, 0, 160, 300, null, null],
|
||||||
|
[0, "방희", null, 0, null, 60, 38, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "법정", null, 0, null, 82, 47, 94, 0, 160, 300, null, null],
|
||||||
|
[0, "방통", null, 0, null, 79, 34, 97, 0, 160, 300, null, null],
|
||||||
|
[0, "방덕", null, 0, null, 89, 94, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "포륭", null, 0, null, 58, 76, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "목순", null, 0, null, 52, 77, 11, 0, 160, 300, null, null],
|
||||||
|
[0, "목록대왕", null, 0, null, 65, 71, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "보즐", null, 0, null, 83, 51, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "만총", null, 0, null, 88, 64, 87, 0, 160, 300, null, null],
|
||||||
|
[0, "모개", null, 0, null, 63, 39, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "맹획", null, 0, null, 81, 88, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "맹체", null, 0, null, 75, 55, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "맹우", null, 0, null, 50, 68, 22, 0, 160, 300, null, null],
|
||||||
|
[0, "유섭", null, 0, null, 62, 79, 24, 0, 160, 300, null, null],
|
||||||
|
[0, "양부", null, 0, null, 62, 48, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "옹개", null, 0, null, 73, 75, 57, 0, 160, 300, null, null],
|
||||||
|
[0, "양의", null, 0, null, 68, 40, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "양호", null, 0, null, 94, 69, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "양홍", null, 0, null, 33, 15, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "양앙", null, 0, null, 68, 72, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "양추", null, 0, null, 52, 65, 40, 0, 160, 300, null, null],
|
||||||
|
[0, "양수", null, 0, null, 46, 23, 83, 0, 160, 300, null, null],
|
||||||
|
[0, "양추2", null, 0, null, 67, 64, 44, 0, 160, 300, null, null],
|
||||||
|
[0, "양송", null, 0, null, 17, 5, 28, 0, 160, 300, null, null],
|
||||||
|
[0, "양임", null, 0, null, 70, 78, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "양조", null, 0, null, 53, 61, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "양백", null, 0, null, 44, 45, 19, 0, 160, 300, null, null],
|
||||||
|
[0, "양부2", null, 0, null, 67, 50, 83, 0, 160, 300, null, null],
|
||||||
|
[0, "양봉", null, 0, null, 66, 65, 31, 0, 160, 300, null, null],
|
||||||
|
[0, "양봉2", null, 0, null, 54, 62, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "뇌동", null, 0, null, 69, 78, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "뇌박", null, 0, null, 62, 70, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "이이", null, 0, null, 63, 77, 19, 0, 160, 300, null, null],
|
||||||
|
[0, "이회", null, 0, null, 79, 58, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "이각", null, 0, null, 69, 72, 24, 0, 160, 300, null, null],
|
||||||
|
[0, "육항", null, 0, null, 94, 68, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "육적", null, 0, null, 20, 7, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "육손", null, 0, null, 95, 71, 96, 0, 160, 300, null, null],
|
||||||
|
[0, "이엄", null, 0, null, 83, 84, 63, 0, 160, 300, null, null],
|
||||||
|
[0, "이유", null, 0, null, 61, 26, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "이숙", null, 0, null, 46, 69, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "이통", null, 0, null, 73, 81, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "이전", null, 0, null, 78, 80, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "이풍", null, 0, null, 69, 74, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "유언", null, 0, null, 61, 38, 80, 0, 160, 300, null, null],
|
||||||
|
[0, "유괴", null, 0, null, 71, 73, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "유기", null, 0, null, 52, 12, 63, 0, 160, 300, null, null],
|
||||||
|
[0, "유우", null, 0, null, 62, 33, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "유훈", null, 0, null, 47, 63, 35, 0, 160, 300, null, null],
|
||||||
|
[0, "유현", null, 0, null, 54, 66, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "유순", null, 0, null, 63, 46, 28, 0, 160, 300, null, null],
|
||||||
|
[0, "유장", null, 0, null, 31, 5, 34, 0, 160, 300, null, null],
|
||||||
|
[0, "유심", null, 0, null, 60, 48, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "유선", null, 0, null, 3, 5, 9, 0, 160, 300, null, null],
|
||||||
|
[0, "유종", null, 0, null, 24, 22, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "유도", null, 0, null, 25, 23, 26, 0, 160, 300, null, null],
|
||||||
|
[0, "유파", null, 0, null, 29, 22, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "유반", null, 0, null, 69, 76, 47, 0, 160, 300, null, null],
|
||||||
|
[0, "유비", null, 0, null, 88, 78, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "유표", null, 0, null, 48, 31, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "유복", null, 0, null, 64, 49, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "유벽", null, 0, null, 70, 72, 47, 0, 160, 300, null, null],
|
||||||
|
[0, "유봉", null, 0, null, 75, 79, 44, 0, 160, 300, null, null],
|
||||||
|
[0, "유엽", null, 0, null, 56, 32, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "유요", null, 0, null, 62, 67, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "여위황", null, 0, null, 58, 63, 29, 0, 160, 300, null, null],
|
||||||
|
[0, "요화", null, 0, null, 73, 76, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "양흥", null, 0, null, 61, 65, 19, 0, 160, 300, null, null],
|
||||||
|
[0, "양습", null, 0, null, 73, 40, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "양서", null, 0, null, 56, 62, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "능조", null, 0, null, 75, 81, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "능통", null, 0, null, 83, 89, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "여개", null, 0, null, 53, 30, 67, 0, 160, 300, null, null],
|
||||||
|
[0, "여건", null, 0, null, 57, 70, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "여광", null, 0, null, 56, 70, 13, 0, 160, 300, null, null],
|
||||||
|
[0, "여상", null, 0, null, 54, 71, 12, 0, 160, 300, null, null],
|
||||||
|
[0, "여대", null, 0, null, 80, 71, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "여범", null, 0, null, 73, 54, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "여포", null, 0, null, 89, 100, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "여몽", null, 0, null, 91, 69, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "윤직", null, 0, null, 46, 42, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "냉포", null, 0, null, 71, 82, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "누규", null, 0, null, 52, 13, 87, 0, 160, 300, null, null],
|
||||||
|
[0, "노숙", null, 0, null, 89, 56, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "노식", null, 0, null, 86, 63, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "범강", null, 0, null, 49, 50, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "장달", null, 0, null, 43, 56, 34, 0, 160, 300, null, null],
|
||||||
|
[0, "규람", null, 0, null, 55, 70, 58, 0, 160, 300, null, null],
|
||||||
|
[0, "대원", null, 0, null, 38, 32, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "왕기", null, 0, null, 81, 64, 86, 0, 160, 300, null, null],
|
||||||
|
[0, "왕상", null, 0, null, 23, 19, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "왕돈", null, 0, null, 60, 66, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "악침", null, 0, null, 73, 75, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "하제", null, 0, null, 83, 61, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "환범", null, 0, null, 40, 11, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "견초", null, 0, null, 72, 79, 57, 0, 160, 300, null, null],
|
||||||
|
[0, "고당륭", null, 0, null, 35, 24, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "오찬", null, 0, null, 68, 41, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "호질", null, 0, null, 73, 46, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "오질", null, 0, null, 16, 29, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "호준", null, 0, null, 79, 76, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "고담", null, 0, null, 53, 23, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "최림", null, 0, null, 32, 22, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "사마망", null, 0, null, 78, 58, 83, 0, 160, 300, null, null],
|
||||||
|
[0, "주이", null, 0, null, 70, 73, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "전단", null, 0, null, 67, 64, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "조우", null, 0, null, 50, 43, 37, 0, 160, 300, null, null],
|
||||||
|
[0, "조상", null, 0, null, 39, 33, 30, 0, 160, 300, null, null],
|
||||||
|
[0, "조방", null, 0, null, 20, 14, 27, 0, 160, 300, null, null],
|
||||||
|
[0, "태사향", null, 0, null, 57, 66, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "장휴", null, 0, null, 63, 27, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "장호", null, 0, null, 75, 74, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "조광", null, 0, null, 67, 71, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "장집", null, 0, null, 76, 29, 80, 0, 160, 300, null, null],
|
||||||
|
[0, "장승", null, 0, null, 77, 55, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "장소2", null, 0, null, 23, 56, 31, 0, 160, 300, null, null],
|
||||||
|
[0, "조통", null, 0, null, 68, 67, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "진표", null, 0, null, 66, 42, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "정무", null, 0, null, 56, 35, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "정봉2", null, 0, null, 66, 66, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "전만", null, 0, null, 51, 73, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "마균", null, 0, null, 22, 17, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "방회", null, 0, null, 69, 75, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "낙통", null, 0, null, 76, 58, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "육개", null, 0, null, 65, 61, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "유찬", null, 0, null, 78, 81, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "유소", null, 0, null, 68, 53, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "요립", null, 0, null, 32, 15, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "여거", null, 0, null, 78, 51, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈첨", null, 0, null, 70, 57, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "손휴", null, 0, null, 57, 42, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "극정", null, 0, null, 42, 23, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "호분", null, 0, null, 71, 76, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "손량", null, 0, null, 32, 26, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "마막", null, 0, null, 34, 12, 44, 0, 160, 300, null, null],
|
||||||
|
[0, "손호", null, 0, null, 41, 73, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "조모", null, 0, null, 54, 61, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "조환", null, 0, null, 30, 28, 30, 0, 160, 300, null, null],
|
||||||
|
[0, "사마유", null, 0, null, 71, 54, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈상", null, 0, null, 64, 79, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "손화", null, 0, null, 31, 39, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "염우", null, 0, null, 52, 61, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "왕경", null, 0, null, 67, 49, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "왕혼", null, 0, null, 74, 71, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "곽혁", null, 0, null, 33, 29, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "가범", null, 0, null, 60, 50, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "서질", null, 0, null, 68, 83, 24, 0, 160, 300, null, null],
|
||||||
|
[0, "손준", null, 0, null, 64, 70, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "손침", null, 0, null, 58, 55, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "우사", null, 0, null, 61, 34, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "진건", null, 0, null, 72, 71, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "동궐", null, 0, null, 65, 59, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "당자", null, 0, null, 61, 71, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "등충", null, 0, null, 76, 80, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "황숭", null, 0, null, 67, 50, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "화핵", null, 0, null, 20, 24, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "허의", null, 0, null, 51, 74, 15, 0, 160, 300, null, null],
|
||||||
|
[0, "송겸", null, 0, null, 66, 78, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "호제", null, 0, null, 57, 39, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "나헌", null, 0, null, 86, 62, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "노숙2", null, 0, null, 73, 53, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "구성", null, 0, null, 63, 70, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "어부라", null, 0, null, 72, 68, 21, 0, 160, 300, null, null],
|
||||||
|
[0, "아하소과", null, 0, null, 61, 76, 13, 0, 160, 300, null, null],
|
||||||
|
[0, "가비능", null, 0, null, 77, 69, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "구력거", null, 0, null, 80, 68, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "강단", null, 0, null, 65, 83, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "황란", null, 0, null, 63, 75, 44, 0, 160, 300, null, null],
|
||||||
|
[0, "호주천", null, 0, null, 70, 71, 40, 0, 160, 300, null, null],
|
||||||
|
[0, "종리목", null, 0, null, 84, 61, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈교", null, 0, null, 62, 27, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "답돈", null, 0, null, 84, 82, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "반임", null, 0, null, 66, 79, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "보도근", null, 0, null, 64, 73, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "미당대왕", null, 0, null, 59, 69, 21, 0, 160, 300, null, null],
|
||||||
|
[0, "유표2", null, 0, null, 73, 74, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "루반", null, 0, null, 65, 76, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "손관", null, 0, null, 72, 78, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "곽석", null, 0, null, 59, 71, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "주조", null, 0, null, 63, 68, 26, 0, 160, 300, null, null],
|
||||||
|
[0, "장거", null, 0, null, 79, 75, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "장순", null, 0, null, 73, 81, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "철리길", null, 0, null, 77, 70, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "주삭", null, 0, null, 54, 60, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "황월영", null, 0, null, 46, 33, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "채염", null, 0, null, 42, 26, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "소교", null, 0, null, 23, 15, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "신헌영", null, 0, null, 65, 35, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "손상향", null, 0, null, 72, 79, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "대교", null, 0, null, 22, 30, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "초선", null, 0, null, 12, 22, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "교모", null, 0, null, 54, 45, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "관구수", null, 0, null, 58, 62, 33, 0, 160, 300, null, null],
|
||||||
|
[0, "관구전", null, 0, null, 63, 47, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "원유", null, 0, null, 56, 40, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "왕광", null, 0, null, 65, 41, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "신창", null, 0, null, 50, 26, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "사마주", null, 0, null, 61, 40, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "양제", null, 0, null, 67, 49, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "성만", null, 0, null, 61, 68, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "오연", null, 0, null, 66, 73, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "맹충", null, 0, null, 47, 28, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "잠혼", null, 0, null, 1, 1, 22, 0, 160, 300, null, null],
|
||||||
|
[0, "사정", null, 0, null, 64, 76, 34, 0, 160, 300, null, null],
|
||||||
|
[0, "심영", null, 0, null, 70, 77, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "도준", null, 0, null, 65, 66, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "만욱", null, 0, null, 21, 25, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "오언", null, 0, null, 76, 81, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "위막", null, 0, null, 57, 62, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "시삭", null, 0, null, 38, 65, 47, 0, 160, 300, null, null],
|
||||||
|
[0, "전속", null, 0, null, 47, 60, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "장화", null, 0, null, 36, 27, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "오거", null, 0, null, 49, 61, 23, 0, 160, 300, null, null],
|
||||||
|
[0, "추정", null, 0, null, 70, 46, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "장특", null, 0, null, 73, 54, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "곽마", null, 0, null, 68, 71, 47, 0, 160, 300, null, null],
|
||||||
|
[0, "석포", null, 0, null, 69, 71, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "견홍", null, 0, null, 70, 74, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "한거자", null, 0, null, 51, 59, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "휴원진", null, 0, null, 52, 68, 45, 0, 160, 300, null, null],
|
||||||
|
[0, "곽원", null, 0, null, 66, 73, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "계옹", null, 0, null, 63, 52, 33, 0, 160, 300, null, null],
|
||||||
|
[0, "이부", null, 0, null, 31, 36, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "왕업", null, 0, null, 33, 6, 35, 0, 160, 300, null, null],
|
||||||
|
[0, "좌혁", null, 0, null, 62, 66, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "화타", null, 0, null, 57, 25, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "사마휘", null, 0, null, 55, 26, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "우길", null, 0, null, 23, 15, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "헌제", null, 0, null, 22, 18, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "백기", null, 0, null, 100, 88, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "한신", null, 0, null, 100, 74, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "악비", null, 0, null, 99, 91, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "항적", null, 0, null, 99, 100, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "악의", null, 0, null, 98, 75, 96, 0, 160, 300, null, null],
|
||||||
|
[0, "영정", null, 0, null, 97, 55, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "강상", null, 0, null, 94, 49, 100, 0, 160, 300, null, null],
|
||||||
|
[0, "전단2", null, 0, null, 96, 75, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "이목", null, 0, null, 96, 69, 88, 0, 160, 300, null, null],
|
||||||
|
[0, "염파", null, 0, null, 97, 96, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "왕전", null, 0, null, 94, 64, 83, 0, 160, 300, null, null],
|
||||||
|
[0, "오기", null, 0, null, 94, 66, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "곽거병", null, 0, null, 93, 92, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "영포", null, 0, null, 82, 91, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "이신", null, 0, null, 81, 88, 63, 0, 160, 300, null, null],
|
||||||
|
[0, "몽념", null, 0, null, 87, 86, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "전기", null, 0, null, 80, 85, 44, 0, 160, 300, null, null],
|
||||||
|
[0, "극신", null, 0, null, 76, 83, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "항연", null, 0, null, 89, 80, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "인상여", null, 0, null, 69, 38, 96, 0, 160, 300, null, null],
|
||||||
|
[0, "장자방", null, 0, null, 72, 40, 100, 0, 160, 300, null, null],
|
||||||
|
[0, "관이오", null, 0, null, 85, 64, 99, 0, 160, 300, null, null],
|
||||||
|
[0, "손빈", null, 0, null, 83, 22, 98, 0, 160, 300, null, null],
|
||||||
|
[0, "소진", null, 0, null, 90, 47, 96, 0, 160, 300, null, null],
|
||||||
|
[0, "범증", null, 0, null, 68, 24, 94, 0, 160, 300, null, null],
|
||||||
|
[0, "장의2", null, 0, null, 75, 23, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "공구", null, 0, null, 68, 70, 91, 0, 160, 300, null, null],
|
||||||
|
[0, "소하", null, 0, null, 56, 27, 97, 0, 160, 300, null, null],
|
||||||
|
[0, "한비", null, 0, null, 49, 18, 97, 0, 160, 300, null, null],
|
||||||
|
[0, "이사", null, 0, null, 48, 24, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "전문", null, 0, null, 79, 67, 89, 0, 160, 300, null, null],
|
||||||
|
[0, "황헐", null, 0, null, 81, 68, 88, 0, 160, 300, null, null],
|
||||||
|
[0, "방난", null, 0, null, 88, 95, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "개섭", null, 0, null, 43, 97, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "형가", null, 0, null, 42, 89, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "유방", null, 0, null, 90, 66, 85, 0, 160, 300, null, null],
|
||||||
|
[0, "하리", null, 0, null, 95, 95, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "헹이", null, 0, null, 95, 62, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "나나", null, 0, null, 91, 52, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "장임2", null, 0, null, 90, 92, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "하야미", null, 0, null, 92, 57, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "이시리스", null, 0, null, 93, 59, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "연채홍", null, 0, null, 91, 52, 91, 0, 160, 300, null, null],
|
||||||
|
[0, "임사영", null, 0, null, 40, 40, 40, 0, 160, 300, null, null],
|
||||||
|
[0, "장군보", null, 0, null, 90, 90, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "크렌스", null, 0, null, 91, 91, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "콘", null, 0, null, 91, 92, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "리즈나", null, 0, null, 90, 56, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "오티누스", null, 0, null, 92, 91, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "네시", null, 0, null, 91, 57, 93, 0, 160, 300, null, null, "안 자고 싸우면 이겨요"],
|
||||||
|
[0, "시뉴카린", null, 0, null, 95, 90, 52, 0, 160, 300, null, null, "피리피리~"],
|
||||||
|
[0, "Hide_D", null, 0, null, 92, 60, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "Pray", null, 0, null, 90, 92, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "사스케", null, 0, null, 91, 94, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "SARS", null, 0, null, 91, 61, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "마요이", null, 0, null, 92, 53, 93, 0, 160, 300, null, null, "로열방 없습니다"],
|
||||||
|
[0, "세정", null, 0, null, 90, 92, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "김나영", null, 0, null, 93, 90, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "독구", null, 0, null, 95, 91, 62, 0, 160, 300, null, null, "웃자 ^-^"],
|
||||||
|
[0, "천괴금", null, 0, null, 33, 66, 99, 0, 160, 300, null, null],
|
||||||
|
[0, "관지평", null, 0, null, 90, 91, 52, 0, 160, 300, null, null, "농장팬티강도소녀!"],
|
||||||
|
[0, "모니카", null, 0, null, 90, 60, 93, 0, 160, 300, null, null, "론조.."],
|
||||||
|
[0, "카리야", null, 0, null, 93, 58, 95, 0, 160, 300, null, null, "깡!"],
|
||||||
|
[0, "rwitch", null, 0, null, 90, 52, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "카류", null, 0, null, 92, 53, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "갈근", null, 0, null, 94, 54, 94, 0, 160, 300, null, null],
|
||||||
|
[0, "페이트", null, 0, null, 92, 59, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "앵벌스", null, 0, null, 94, 91, 57, 0, 160, 300, null, null, "다람쥐는 위대하고 그 외에 다른 설치류는 없다"],
|
||||||
|
[0, "조밧", null, 0, null, 91, 93, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "슬라임", null, 0, null, 90, 56, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "제노에이지", null, 0, null, 93, 61, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "평민킬러", null, 0, null, 95, 92, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "아유", null, 0, null, 91, 54, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "로리", null, 0, null, 92, 55, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "n아텐 누", null, 0, null, 92, 55, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "Card", null, 0, null, 91, 90, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "Per", null, 0, null, 93, 57, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "아쉐리트", null, 0, null, 94, 55, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "외심장", null, 0, null, 91, 57, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "카이스트", null, 0, null, 91, 53, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "아키라", null, 0, null, 80, 50, 80, 0, 160, 300, null, null, "뻐끔뻐끔"],
|
||||||
|
[0, "카오스피닉스", null, 0, null, 93, 58, 92, 0, 160, 300, null, null, "=ㅁ="],
|
||||||
|
[0, "민트토끼", null, 0, null, 92, 54, 90, 0, 160, 300, null, null, "나 바보 아니다!"],
|
||||||
|
[0, "くま", null, 0, null, 90, 92, 57, 0, 160, 300, null, null],
|
||||||
|
[0, "북오더", null, 0, null, 91, 58, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "이쓰미", null, 0, null, 92, 58, 91, 0, 160, 300, null, null],
|
||||||
|
[0, "개미호랑이", null, 0, null, 91, 55, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "수장", null, 0, null, 93, 57, 91, 0, 160, 300, null, null],
|
||||||
|
[0, "이드", null, 0, null, 92, 93, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "호무새", null, 0, null, 91, 53, 91, 0, 160, 300, null, null, "호우~"],
|
||||||
|
[0, "박일아", null, 0, null, 93, 59, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "유기체", null, 0, null, 92, 56, 95, 0, 160, 300, null, null, "흠... 그렇다면 어쩔 수 없이 흉노로 가야겠군요..."],
|
||||||
|
[0, "황약사", null, 0, null, 92, 92, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "하후연묘재", null, 0, null, 92, 52, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "초절정미녀", null, 0, null, 95, 65, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈여포", null, 0, null, 92, 54, 91, 0, 160, 300, null, null],
|
||||||
|
[0, "온몸이근육", null, 0, null, 93, 93, 52, 0, 160, 300, null, null, "불끈불끈"],
|
||||||
|
[0, "네이미", null, 0, null, 91, 93, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "ARES군주", null, 0, null, 90, 93, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "중달", null, 0, null, 93, 92, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "쿠레나이", null, 0, null, 90, 52, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "만샘", null, 0, null, 92, 55, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "우돌", null, 0, null, 93, 91, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "아이린", null, 0, null, 93, 54, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "유카", null, 0, null, 91, 92, 57, 0, 160, 300, null, null],
|
||||||
|
[0, "기", null, 0, null, 95, 90, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "병리학적자세", null, 0, null, 91, 55, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "료우기시키", null, 0, null, 92, 90, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "Cure", null, 0, null, 92, 92, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "40장로", null, 0, null, 85, 85, 85, 0, 160, 300, null, null]
|
||||||
|
],
|
||||||
|
"initialEvents":[
|
||||||
|
|
||||||
|
],
|
||||||
|
"events":[
|
||||||
|
[
|
||||||
|
"destroy_nation", 1000,
|
||||||
|
["and",
|
||||||
|
["Date", ">=", 183, 1],
|
||||||
|
["RemainNation", "==", 1]
|
||||||
|
],
|
||||||
|
["BlockScoutAction"],
|
||||||
|
["DeleteEvent"]
|
||||||
|
]
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,915 @@
|
|||||||
|
{
|
||||||
|
"title": "【가상모드25-b】 악질유저무쌍!(비급)",
|
||||||
|
"startYear": 180,
|
||||||
|
"history": [
|
||||||
|
"<C>●</>180년 1월:<L><b>【가상모드25-b】</b>악질유저무쌍!(비급)</>",
|
||||||
|
"<C>●</>180년 1월:<L><b>【이벤트】</b></>최고의 악질유저를 가려라!"
|
||||||
|
],
|
||||||
|
"stat": {
|
||||||
|
"total": 310,
|
||||||
|
"min": 40,
|
||||||
|
"max": 140
|
||||||
|
},
|
||||||
|
"iconPath": ".",
|
||||||
|
"fiction": 1,
|
||||||
|
"nation":[
|
||||||
|
|
||||||
|
],
|
||||||
|
"diplomacy":[],
|
||||||
|
"const": {
|
||||||
|
"npcBanMessageProb":0,
|
||||||
|
"npcSeizureMessageProb":0,
|
||||||
|
"npcMessageFreqByDay":8,
|
||||||
|
"availableSpecialWar": [
|
||||||
|
"che_귀병", "che_신산", "che_환술", "che_집중", "che_신중", "che_반계",
|
||||||
|
"che_보병", "che_궁병", "che_기병", "che_공성",
|
||||||
|
"che_돌격", "che_무쌍", "che_견고", "che_위압",
|
||||||
|
"che_저격", "che_필살", "che_징병", "che_의술", "che_격노", "che_척사"
|
||||||
|
],
|
||||||
|
"allItems": {
|
||||||
|
"horse": {
|
||||||
|
"che_명마_01_노기": 0,
|
||||||
|
"che_명마_02_조랑": 0,
|
||||||
|
"che_명마_03_노새": 0,
|
||||||
|
"che_명마_04_나귀": 0,
|
||||||
|
"che_명마_05_갈색마": 0,
|
||||||
|
"che_명마_06_흑색마": 0,
|
||||||
|
|
||||||
|
"che_명마_07_백마" : 2,
|
||||||
|
"che_명마_07_기주마" : 2,
|
||||||
|
"che_명마_07_오환마" : 2,
|
||||||
|
"che_명마_07_백상" : 2,
|
||||||
|
"che_명마_08_양주마" : 2,
|
||||||
|
"che_명마_08_흉노마" : 2,
|
||||||
|
"che_명마_09_과하마" : 2,
|
||||||
|
"che_명마_09_의남백마" : 2,
|
||||||
|
"che_명마_10_대완마" : 2,
|
||||||
|
"che_명마_10_옥추마" : 2,
|
||||||
|
"che_명마_11_서량마" : 2,
|
||||||
|
"che_명마_11_화종마" : 2,
|
||||||
|
"che_명마_12_사륜거" : 2,
|
||||||
|
"che_명마_12_옥란백용구": 2,
|
||||||
|
"che_명마_13_절영" : 2,
|
||||||
|
"che_명마_13_적로" : 2,
|
||||||
|
"che_명마_14_적란마" : 2,
|
||||||
|
"che_명마_14_조황비전" : 2,
|
||||||
|
"che_명마_15_한혈마" : 2,
|
||||||
|
"che_명마_15_적토마" : 2
|
||||||
|
},
|
||||||
|
"weapon": {
|
||||||
|
"che_무기_01_단도": 0,
|
||||||
|
"che_무기_02_단궁": 0,
|
||||||
|
"che_무기_03_단극": 0,
|
||||||
|
"che_무기_04_목검": 0,
|
||||||
|
"che_무기_05_죽창": 0,
|
||||||
|
"che_무기_06_소부": 0,
|
||||||
|
|
||||||
|
"che_무기_07_동추": 2,
|
||||||
|
"che_무기_07_철편": 2,
|
||||||
|
"che_무기_07_철쇄": 2,
|
||||||
|
"che_무기_07_맥궁": 2,
|
||||||
|
"che_무기_08_유성추": 2,
|
||||||
|
"che_무기_08_철질여골": 2,
|
||||||
|
"che_무기_09_쌍철극": 2,
|
||||||
|
"che_무기_09_동호비궁": 2,
|
||||||
|
"che_무기_10_삼첨도": 2,
|
||||||
|
"che_무기_10_대부": 2,
|
||||||
|
"che_무기_11_고정도": 2,
|
||||||
|
"che_무기_11_이광궁": 2,
|
||||||
|
"che_무기_12_철척사모": 2,
|
||||||
|
"che_무기_12_칠성검": 2,
|
||||||
|
"che_무기_13_사모": 2,
|
||||||
|
"che_무기_13_양유기궁": 2,
|
||||||
|
"che_무기_14_언월도": 2,
|
||||||
|
"che_무기_14_방천화극": 2,
|
||||||
|
"che_무기_15_청홍검": 2,
|
||||||
|
"che_무기_15_의천검": 2
|
||||||
|
},
|
||||||
|
"book": {
|
||||||
|
"che_서적_01_효경전": 0,
|
||||||
|
"che_서적_02_회남자": 0,
|
||||||
|
"che_서적_03_변도론": 0,
|
||||||
|
"che_서적_04_건상역주": 0,
|
||||||
|
"che_서적_05_여씨춘추": 0,
|
||||||
|
"che_서적_06_사민월령": 0,
|
||||||
|
|
||||||
|
"che_서적_07_위료자": 2,
|
||||||
|
"che_서적_07_사마법": 2,
|
||||||
|
"che_서적_07_한서": 2,
|
||||||
|
"che_서적_07_논어": 2,
|
||||||
|
"che_서적_08_전론": 2,
|
||||||
|
"che_서적_08_사기": 2,
|
||||||
|
"che_서적_09_장자": 2,
|
||||||
|
"che_서적_09_역경": 2,
|
||||||
|
"che_서적_10_시경": 2,
|
||||||
|
"che_서적_10_구국론": 2,
|
||||||
|
"che_서적_11_상군서": 2,
|
||||||
|
"che_서적_11_춘추전": 2,
|
||||||
|
"che_서적_12_산해경": 2,
|
||||||
|
"che_서적_12_맹덕신서": 2,
|
||||||
|
"che_서적_13_관자": 2,
|
||||||
|
"che_서적_13_병법24편": 2,
|
||||||
|
"che_서적_14_한비자": 2,
|
||||||
|
"che_서적_14_오자병법": 2,
|
||||||
|
"che_서적_15_노자": 2,
|
||||||
|
"che_서적_15_손자병법": 2
|
||||||
|
},
|
||||||
|
"item": {
|
||||||
|
"che_치료_환약": 0,
|
||||||
|
"che_저격_수극": 0,
|
||||||
|
"che_사기_탁주": 0,
|
||||||
|
"che_훈련_청주": 0,
|
||||||
|
"che_계략_이추": 0,
|
||||||
|
"che_계략_향낭": 0,
|
||||||
|
|
||||||
|
"event_전투특기_격노": 0,
|
||||||
|
"event_전투특기_견고": 0,
|
||||||
|
"event_전투특기_공성": 0,
|
||||||
|
"event_전투특기_궁병": 0,
|
||||||
|
"event_전투특기_귀병": 0,
|
||||||
|
"event_전투특기_기병": 0,
|
||||||
|
"event_전투특기_돌격": 0,
|
||||||
|
"event_전투특기_무쌍": 0,
|
||||||
|
"event_전투특기_반계": 0,
|
||||||
|
"event_전투특기_보병": 0,
|
||||||
|
"event_전투특기_신산": 0,
|
||||||
|
"event_전투특기_신중": 0,
|
||||||
|
"event_전투특기_위압": 0,
|
||||||
|
"event_전투특기_의술": 0,
|
||||||
|
"event_전투특기_저격": 0,
|
||||||
|
"event_전투특기_집중": 0,
|
||||||
|
"event_전투특기_징병": 0,
|
||||||
|
"event_전투특기_척사": 0,
|
||||||
|
"event_전투특기_필살": 0,
|
||||||
|
"event_전투특기_환술": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"general":[
|
||||||
|
[0, "아회남", null, 0, null, 65, 74, 26, 0, 160, 300, null, null],
|
||||||
|
[0, "이적", null, 0, null, 40, 24, 84, 0, 160, 300, null, null],
|
||||||
|
[0, "윤상", null, 0, null, 51, 44, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "윤묵", null, 0, null, 26, 15, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "우금", null, 0, null, 85, 82, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "위관", null, 0, null, 69, 46, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "원윤", null, 0, null, 32, 14, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "원희", null, 0, null, 66, 43, 63, 0, 160, 300, null, null],
|
||||||
|
[0, "염행", null, 0, null, 78, 90, 58, 0, 160, 300, null, null],
|
||||||
|
[0, "염유", null, 0, null, 71, 50, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "원술", null, 0, null, 76, 55, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "원상", null, 0, null, 63, 75, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "원소", null, 0, null, 90, 62, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "염상", null, 0, null, 40, 27, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "원담", null, 0, null, 60, 78, 30, 0, 160, 300, null, null],
|
||||||
|
[0, "염포", null, 0, null, 40, 25, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "왕위", null, 0, null, 60, 70, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "왕윤", null, 0, null, 26, 6, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "왕항", null, 0, null, 76, 43, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "왕찬", null, 0, null, 15, 3, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "왕수", null, 0, null, 54, 27, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "왕숙", null, 0, null, 36, 22, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "왕준", null, 0, null, 85, 64, 84, 0, 160, 300, null, null],
|
||||||
|
[0, "왕쌍", null, 0, null, 67, 88, 19, 0, 160, 300, null, null],
|
||||||
|
[0, "왕창", null, 0, null, 74, 57, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "왕평", null, 0, null, 88, 81, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "왕보", null, 0, null, 62, 41, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "왕문", null, 0, null, 65, 64, 31, 0, 160, 300, null, null],
|
||||||
|
[0, "왕릉", null, 0, null, 74, 50, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "왕루", null, 0, null, 28, 30, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "왕랑", null, 0, null, 47, 35, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "온회", null, 0, null, 62, 36, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "하안", null, 0, null, 15, 30, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "괴월", null, 0, null, 50, 38, 85, 0, 160, 300, null, null],
|
||||||
|
[0, "괴량", null, 0, null, 68, 33, 88, 0, 160, 300, null, null],
|
||||||
|
[0, "가화", null, 0, null, 49, 65, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "가규", null, 0, null, 78, 61, 84, 0, 160, 300, null, null],
|
||||||
|
[0, "하의", null, 0, null, 56, 69, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "화흠", null, 0, null, 51, 33, 88, 0, 160, 300, null, null],
|
||||||
|
[0, "가후", null, 0, null, 71, 40, 98, 0, 160, 300, null, null],
|
||||||
|
[0, "곽가", null, 0, null, 70, 41, 97, 0, 160, 300, null, null],
|
||||||
|
[0, "악환", null, 0, null, 65, 80, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "곽사", null, 0, null, 64, 76, 13, 0, 160, 300, null, null],
|
||||||
|
[0, "악취", null, 0, null, 53, 66, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "곽준", null, 0, null, 73, 52, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "학소", null, 0, null, 88, 63, 83, 0, 160, 300, null, null],
|
||||||
|
[0, "악진", null, 0, null, 80, 85, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "곽도", null, 0, null, 62, 50, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "학맹", null, 0, null, 62, 67, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "곽유지", null, 0, null, 28, 9, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "곽익", null, 0, null, 73, 69, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "곽회", null, 0, null, 90, 66, 85, 0, 160, 300, null, null],
|
||||||
|
[0, "하후위", null, 0, null, 71, 73, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "하후연", null, 0, null, 95, 92, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "하후은", null, 0, null, 63, 72, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "하후화", null, 0, null, 48, 51, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "하후혜", null, 0, null, 50, 44, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "하후현", null, 0, null, 54, 39, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "하후상", null, 0, null, 79, 55, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "하후덕", null, 0, null, 69, 73, 32, 0, 160, 300, null, null],
|
||||||
|
[0, "하후돈", null, 0, null, 91, 88, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "하후패", null, 0, null, 79, 85, 63, 0, 160, 300, null, null],
|
||||||
|
[0, "하후무", null, 0, null, 20, 7, 4, 0, 160, 300, null, null],
|
||||||
|
[0, "가충", null, 0, null, 54, 31, 89, 0, 160, 300, null, null],
|
||||||
|
[0, "하진", null, 0, null, 68, 54, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "화웅", null, 0, null, 78, 90, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "한윤", null, 0, null, 26, 29, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "관우", null, 0, null, 96, 99, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "환계", null, 0, null, 25, 26, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "관해", null, 0, null, 70, 82, 10, 0, 160, 300, null, null],
|
||||||
|
[0, "관구검", null, 0, null, 84, 86, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "한현", null, 0, null, 22, 33, 7, 0, 160, 300, null, null],
|
||||||
|
[0, "한호", null, 0, null, 73, 61, 84, 0, 160, 300, null, null],
|
||||||
|
[0, "관흥", null, 0, null, 76, 84, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "관색", null, 0, null, 74, 83, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "한수", null, 0, null, 78, 58, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "한숭", null, 0, null, 25, 15, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "관정", null, 0, null, 36, 52, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "한섬", null, 0, null, 69, 66, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "감택", null, 0, null, 51, 49, 83, 0, 160, 300, null, null],
|
||||||
|
[0, "한충", null, 0, null, 64, 67, 18, 0, 160, 300, null, null],
|
||||||
|
[0, "한당", null, 0, null, 76, 85, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "한덕", null, 0, null, 63, 76, 25, 0, 160, 300, null, null],
|
||||||
|
[0, "감녕", null, 0, null, 92, 95, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "한복", null, 0, null, 28, 3, 27, 0, 160, 300, null, null],
|
||||||
|
[0, "관평", null, 0, null, 78, 82, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "간옹", null, 0, null, 20, 32, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "안량", null, 0, null, 88, 96, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "위연", null, 0, null, 91, 90, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "국의", null, 0, null, 84, 78, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "희지재", null, 0, null, 63, 35, 91, 0, 160, 300, null, null],
|
||||||
|
[0, "위속", null, 0, null, 67, 78, 31, 0, 160, 300, null, null],
|
||||||
|
[0, "위유", null, 0, null, 46, 29, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "우금2", null, 0, null, 72, 79, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "우보", null, 0, null, 38, 60, 21, 0, 160, 300, null, null],
|
||||||
|
[0, "강유", null, 0, null, 92, 72, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "공지", null, 0, null, 43, 53, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "교유", null, 0, null, 64, 69, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "공도", null, 0, null, 59, 70, 23, 0, 160, 300, null, null],
|
||||||
|
[0, "허공", null, 0, null, 44, 66, 64, 0, 160, 300, null, null],
|
||||||
|
[0, "허정", null, 0, null, 23, 5, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "허저", null, 0, null, 74, 97, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "허유", null, 0, null, 36, 21, 80, 0, 160, 300, null, null],
|
||||||
|
[0, "기령", null, 0, null, 85, 84, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "김의", null, 0, null, 32, 38, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "김배삼결", null, 0, null, 64, 76, 19, 0, 160, 300, null, null],
|
||||||
|
[0, "김선", null, 0, null, 52, 68, 13, 0, 160, 300, null, null],
|
||||||
|
[0, "우번", null, 0, null, 46, 46, 87, 0, 160, 300, null, null],
|
||||||
|
[0, "형도영", null, 0, null, 69, 79, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "엄안", null, 0, null, 82, 83, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "엄망", null, 0, null, 68, 71, 40, 0, 160, 300, null, null],
|
||||||
|
[0, "엄준", null, 0, null, 41, 12, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "엄정", null, 0, null, 50, 55, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "엄백호", null, 0, null, 67, 70, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "엄여", null, 0, null, 61, 78, 44, 0, 160, 300, null, null],
|
||||||
|
[0, "오의", null, 0, null, 79, 73, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "황개", null, 0, null, 80, 86, 64, 0, 160, 300, null, null],
|
||||||
|
[0, "고간", null, 0, null, 74, 56, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "황권", null, 0, null, 75, 59, 88, 0, 160, 300, null, null],
|
||||||
|
[0, "고유", null, 0, null, 57, 43, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "고순", null, 0, null, 87, 89, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "고상", null, 0, null, 68, 68, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "고승", null, 0, null, 67, 73, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "후성", null, 0, null, 74, 75, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "후선", null, 0, null, 63, 66, 34, 0, 160, 300, null, null],
|
||||||
|
[0, "황조", null, 0, null, 81, 66, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "공손월", null, 0, null, 74, 72, 47, 0, 160, 300, null, null],
|
||||||
|
[0, "공손연", null, 0, null, 65, 70, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "공손공", null, 0, null, 39, 17, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "공손강", null, 0, null, 72, 66, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "공손찬", null, 0, null, 86, 82, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "공손속", null, 0, null, 63, 68, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "공손도", null, 0, null, 67, 71, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "공손범", null, 0, null, 73, 69, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "황충", null, 0, null, 88, 96, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "고정", null, 0, null, 55, 63, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "고패", null, 0, null, 66, 48, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "황보숭", null, 0, null, 91, 61, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "공융", null, 0, null, 30, 5, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "고람", null, 0, null, 76, 82, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "오경", null, 0, null, 69, 66, 45, 0, 160, 300, null, null],
|
||||||
|
[0, "호거아", null, 0, null, 70, 82, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "호진", null, 0, null, 65, 74, 12, 0, 160, 300, null, null],
|
||||||
|
[0, "올돌골", null, 0, null, 79, 86, 11, 0, 160, 300, null, null],
|
||||||
|
[0, "호반", null, 0, null, 55, 55, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "오반", null, 0, null, 74, 71, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "고옹", null, 0, null, 52, 18, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "오란", null, 0, null, 68, 80, 35, 0, 160, 300, null, null],
|
||||||
|
[0, "채화", null, 0, null, 39, 50, 1, 0, 160, 300, null, null],
|
||||||
|
[0, "채중", null, 0, null, 40, 54, 2, 0, 160, 300, null, null],
|
||||||
|
[0, "채모", null, 0, null, 70, 55, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "착융", null, 0, null, 60, 69, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "사마의", null, 0, null, 99, 63, 98, 0, 160, 300, null, null],
|
||||||
|
[0, "사마염", null, 0, null, 69, 59, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "사마사", null, 0, null, 84, 64, 89, 0, 160, 300, null, null],
|
||||||
|
[0, "사마소", null, 0, null, 85, 57, 88, 0, 160, 300, null, null],
|
||||||
|
[0, "사마부", null, 0, null, 70, 37, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "사마랑", null, 0, null, 20, 21, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "사마가", null, 0, null, 66, 84, 25, 0, 160, 300, null, null],
|
||||||
|
[0, "주흔", null, 0, null, 65, 51, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "주앙", null, 0, null, 74, 65, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "주지", null, 0, null, 73, 85, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "주창", null, 0, null, 68, 77, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "주태", null, 0, null, 84, 90, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "주방", null, 0, null, 52, 41, 80, 0, 160, 300, null, null],
|
||||||
|
[0, "주유", null, 0, null, 97, 71, 97, 0, 160, 300, null, null],
|
||||||
|
[0, "주환", null, 0, null, 87, 84, 64, 0, 160, 300, null, null],
|
||||||
|
[0, "주거", null, 0, null, 77, 57, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "축융", null, 0, null, 72, 75, 35, 0, 160, 300, null, null],
|
||||||
|
[0, "주준", null, 0, null, 89, 57, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "주연", null, 0, null, 86, 75, 57, 0, 160, 300, null, null],
|
||||||
|
[0, "주치", null, 0, null, 71, 56, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "주포", null, 0, null, 68, 73, 34, 0, 160, 300, null, null],
|
||||||
|
[0, "주령", null, 0, null, 78, 73, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "순욱", null, 0, null, 78, 38, 97, 0, 160, 300, null, null],
|
||||||
|
[0, "순우경", null, 0, null, 78, 66, 29, 0, 160, 300, null, null],
|
||||||
|
[0, "순심", null, 0, null, 45, 25, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "순유", null, 0, null, 80, 35, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "장완", null, 0, null, 78, 34, 89, 0, 160, 300, null, null],
|
||||||
|
[0, "종회", null, 0, null, 88, 62, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "장간", null, 0, null, 19, 6, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "장의거", null, 0, null, 71, 41, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "장흠", null, 0, null, 78, 85, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "장제3", null, 0, null, 62, 43, 85, 0, 160, 300, null, null],
|
||||||
|
[0, "초주", null, 0, null, 16, 3, 67, 0, 160, 300, null, null],
|
||||||
|
[0, "초촉", null, 0, null, 65, 76, 33, 0, 160, 300, null, null],
|
||||||
|
[0, "향총", null, 0, null, 76, 56, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "종요", null, 0, null, 79, 24, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "향랑", null, 0, null, 28, 18, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "서영", null, 0, null, 92, 80, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈각", null, 0, null, 72, 47, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈근", null, 0, null, 75, 34, 85, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈균", null, 0, null, 29, 25, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈탄", null, 0, null, 72, 54, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈량", null, 0, null, 98, 43, 100, 0, 160, 300, null, null],
|
||||||
|
[0, "서황", null, 0, null, 95, 94, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "서서", null, 0, null, 85, 64, 94, 0, 160, 300, null, null],
|
||||||
|
[0, "서성", null, 0, null, 86, 81, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "서막", null, 0, null, 55, 32, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "신의", null, 0, null, 55, 59, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "신탐", null, 0, null, 56, 62, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "심배", null, 0, null, 80, 60, 84, 0, 160, 300, null, null],
|
||||||
|
[0, "신비", null, 0, null, 42, 24, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "신평", null, 0, null, 69, 43, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "진복", null, 0, null, 31, 7, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "진랑", null, 0, null, 58, 70, 35, 0, 160, 300, null, null],
|
||||||
|
[0, "휴고", null, 0, null, 63, 71, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "추단", null, 0, null, 61, 64, 34, 0, 160, 300, null, null],
|
||||||
|
[0, "성의", null, 0, null, 74, 72, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "성공영", null, 0, null, 73, 58, 80, 0, 160, 300, null, null],
|
||||||
|
[0, "설종", null, 0, null, 34, 16, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "단경", null, 0, null, 71, 68, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "전종", null, 0, null, 78, 55, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "조예", null, 0, null, 72, 52, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "조휴", null, 0, null, 84, 78, 58, 0, 160, 300, null, null],
|
||||||
|
[0, "송헌", null, 0, null, 68, 77, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "조앙", null, 0, null, 78, 50, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "조홍", null, 0, null, 80, 75, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "조순", null, 0, null, 85, 83, 63, 0, 160, 300, null, null],
|
||||||
|
[0, "조창", null, 0, null, 86, 91, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "조식", null, 0, null, 45, 22, 86, 0, 160, 300, null, null],
|
||||||
|
[0, "조진", null, 0, null, 88, 74, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "조인", null, 0, null, 94, 90, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "조성", null, 0, null, 54, 74, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "조조", null, 0, null, 100, 72, 96, 0, 160, 300, null, null],
|
||||||
|
[0, "조충", null, 0, null, 43, 21, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "장패", null, 0, null, 78, 86, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "조비", null, 0, null, 75, 64, 87, 0, 160, 300, null, null],
|
||||||
|
[0, "조표", null, 0, null, 54, 69, 32, 0, 160, 300, null, null],
|
||||||
|
[0, "저수", null, 0, null, 86, 46, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "소비", null, 0, null, 69, 45, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "조무", null, 0, null, 70, 71, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "손환", null, 0, null, 82, 56, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "손견", null, 0, null, 94, 95, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "손건", null, 0, null, 44, 33, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "손권", null, 0, null, 86, 61, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "손교", null, 0, null, 77, 72, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "손책", null, 0, null, 93, 94, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "손소", null, 0, null, 82, 79, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "손정", null, 0, null, 66, 53, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "손중", null, 0, null, 62, 71, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "손등", null, 0, null, 62, 37, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "손유", null, 0, null, 77, 70, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "손익", null, 0, null, 67, 83, 27, 0, 160, 300, null, null],
|
||||||
|
[0, "손례", null, 0, null, 78, 81, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "태사자", null, 0, null, 94, 94, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "대래동주", null, 0, null, 51, 53, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "대릉", null, 0, null, 70, 75, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "타사대왕", null, 0, null, 62, 48, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "담웅", null, 0, null, 58, 73, 14, 0, 160, 300, null, null],
|
||||||
|
[0, "장윤", null, 0, null, 72, 67, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "조운", null, 0, null, 90, 96, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "장위", null, 0, null, 74, 66, 45, 0, 160, 300, null, null],
|
||||||
|
[0, "장영", null, 0, null, 75, 74, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "장연", null, 0, null, 76, 81, 57, 0, 160, 300, null, null],
|
||||||
|
[0, "장횡", null, 0, null, 59, 70, 23, 0, 160, 300, null, null],
|
||||||
|
[0, "장온", null, 0, null, 32, 10, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "장개", null, 0, null, 34, 66, 8, 0, 160, 300, null, null],
|
||||||
|
[0, "장각", null, 0, null, 87, 35, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "장기", null, 0, null, 74, 35, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "장의", null, 0, null, 79, 55, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "장훈", null, 0, null, 72, 68, 41, 0, 160, 300, null, null],
|
||||||
|
[0, "장굉", null, 0, null, 24, 22, 86, 0, 160, 300, null, null],
|
||||||
|
[0, "장합", null, 0, null, 92, 89, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "조홍2", null, 0, null, 66, 72, 28, 0, 160, 300, null, null],
|
||||||
|
[0, "장제2", null, 0, null, 70, 66, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "장수", null, 0, null, 80, 73, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "장소", null, 0, null, 41, 13, 87, 0, 160, 300, null, null],
|
||||||
|
[0, "장송", null, 0, null, 40, 6, 85, 0, 160, 300, null, null],
|
||||||
|
[0, "장임", null, 0, null, 85, 84, 64, 0, 160, 300, null, null],
|
||||||
|
[0, "장제", null, 0, null, 67, 43, 80, 0, 160, 300, null, null],
|
||||||
|
[0, "장막", null, 0, null, 52, 53, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "조범", null, 0, null, 28, 21, 32, 0, 160, 300, null, null],
|
||||||
|
[0, "장비", null, 0, null, 87, 98, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "장포", null, 0, null, 78, 84, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "장보", null, 0, null, 83, 60, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "장만성", null, 0, null, 75, 81, 45, 0, 160, 300, null, null],
|
||||||
|
[0, "장양", null, 0, null, 72, 70, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "장익", null, 0, null, 75, 55, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "장료", null, 0, null, 96, 94, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "장량", null, 0, null, 78, 80, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "조루", null, 0, null, 70, 43, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "장로", null, 0, null, 65, 42, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "진횡", null, 0, null, 64, 63, 26, 0, 160, 300, null, null],
|
||||||
|
[0, "진응", null, 0, null, 62, 72, 45, 0, 160, 300, null, null],
|
||||||
|
[0, "진기", null, 0, null, 58, 65, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "진궁", null, 0, null, 84, 55, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "진교", null, 0, null, 61, 27, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "진군", null, 0, null, 32, 14, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "진규", null, 0, null, 30, 4, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "진식", null, 0, null, 70, 71, 25, 0, 160, 300, null, null],
|
||||||
|
[0, "진진", null, 0, null, 46, 46, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "진태", null, 0, null, 86, 68, 89, 0, 160, 300, null, null],
|
||||||
|
[0, "진등", null, 0, null, 79, 59, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "진도", null, 0, null, 82, 78, 58, 0, 160, 300, null, null],
|
||||||
|
[0, "진무", null, 0, null, 76, 87, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "진란", null, 0, null, 66, 69, 40, 0, 160, 300, null, null],
|
||||||
|
[0, "진림", null, 0, null, 25, 9, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "정욱", null, 0, null, 76, 49, 94, 0, 160, 300, null, null],
|
||||||
|
[0, "정원지", null, 0, null, 69, 74, 17, 0, 160, 300, null, null],
|
||||||
|
[0, "정은", null, 0, null, 69, 73, 40, 0, 160, 300, null, null],
|
||||||
|
[0, "정원", null, 0, null, 70, 76, 35, 0, 160, 300, null, null],
|
||||||
|
[0, "정보", null, 0, null, 84, 79, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "정봉", null, 0, null, 81, 92, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "전위", null, 0, null, 79, 98, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "전해", null, 0, null, 68, 65, 45, 0, 160, 300, null, null],
|
||||||
|
[0, "전주", null, 0, null, 66, 51, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "전풍", null, 0, null, 82, 43, 96, 0, 160, 300, null, null],
|
||||||
|
[0, "전예", null, 0, null, 93, 85, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "동윤", null, 0, null, 47, 28, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "동화", null, 0, null, 57, 34, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "등애", null, 0, null, 92, 73, 94, 0, 160, 300, null, null],
|
||||||
|
[0, "도겸", null, 0, null, 51, 27, 64, 0, 160, 300, null, null],
|
||||||
|
[0, "등현", null, 0, null, 61, 73, 45, 0, 160, 300, null, null],
|
||||||
|
[0, "등지", null, 0, null, 73, 52, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "동습", null, 0, null, 72, 85, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "동승", null, 0, null, 56, 53, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "동소", null, 0, null, 34, 25, 80, 0, 160, 300, null, null],
|
||||||
|
[0, "동탁", null, 0, null, 91, 87, 67, 0, 160, 300, null, null],
|
||||||
|
[0, "동도나", null, 0, null, 68, 73, 31, 0, 160, 300, null, null],
|
||||||
|
[0, "동민", null, 0, null, 49, 60, 25, 0, 160, 300, null, null],
|
||||||
|
[0, "등무", null, 0, null, 61, 75, 29, 0, 160, 300, null, null],
|
||||||
|
[0, "두기", null, 0, null, 74, 43, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "두예", null, 0, null, 96, 69, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "배원소", null, 0, null, 49, 65, 25, 0, 160, 300, null, null],
|
||||||
|
[0, "마완", null, 0, null, 71, 74, 16, 0, 160, 300, null, null],
|
||||||
|
[0, "마휴", null, 0, null, 68, 73, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "파재", null, 0, null, 74, 74, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "마준", null, 0, null, 38, 52, 31, 0, 160, 300, null, null],
|
||||||
|
[0, "마속", null, 0, null, 61, 59, 84, 0, 160, 300, null, null],
|
||||||
|
[0, "마대", null, 0, null, 79, 85, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "마충", null, 0, null, 78, 72, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "마초", null, 0, null, 86, 97, 44, 0, 160, 300, null, null],
|
||||||
|
[0, "마철", null, 0, null, 70, 62, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "마등", null, 0, null, 85, 80, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "마량", null, 0, null, 53, 23, 85, 0, 160, 300, null, null],
|
||||||
|
[0, "반준", null, 0, null, 61, 46, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "반장", null, 0, null, 76, 80, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "번조", null, 0, null, 66, 73, 31, 0, 160, 300, null, null],
|
||||||
|
[0, "번능", null, 0, null, 69, 61, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "반봉", null, 0, null, 56, 77, 4, 0, 160, 300, null, null],
|
||||||
|
[0, "비의", null, 0, null, 82, 56, 88, 0, 160, 300, null, null],
|
||||||
|
[0, "비연", null, 0, null, 60, 66, 21, 0, 160, 300, null, null],
|
||||||
|
[0, "비시", null, 0, null, 18, 28, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "미축", null, 0, null, 33, 29, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "미방", null, 0, null, 54, 61, 32, 0, 160, 300, null, null],
|
||||||
|
[0, "비요", null, 0, null, 70, 52, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "무안국", null, 0, null, 70, 79, 34, 0, 160, 300, null, null],
|
||||||
|
[0, "풍습", null, 0, null, 72, 71, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "부사인", null, 0, null, 46, 63, 37, 0, 160, 300, null, null],
|
||||||
|
[0, "부첨", null, 0, null, 73, 85, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "부손", null, 0, null, 29, 13, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "문앙", null, 0, null, 76, 96, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "문흠", null, 0, null, 74, 79, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "문추", null, 0, null, 87, 95, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "문빙", null, 0, null, 88, 85, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "변희", null, 0, null, 56, 70, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "망아장", null, 0, null, 45, 79, 3, 0, 160, 300, null, null],
|
||||||
|
[0, "봉기", null, 0, null, 56, 48, 84, 0, 160, 300, null, null],
|
||||||
|
[0, "방희", null, 0, null, 60, 38, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "법정", null, 0, null, 82, 47, 94, 0, 160, 300, null, null],
|
||||||
|
[0, "방통", null, 0, null, 79, 34, 97, 0, 160, 300, null, null],
|
||||||
|
[0, "방덕", null, 0, null, 89, 94, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "포륭", null, 0, null, 58, 76, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "목순", null, 0, null, 52, 77, 11, 0, 160, 300, null, null],
|
||||||
|
[0, "목록대왕", null, 0, null, 65, 71, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "보즐", null, 0, null, 83, 51, 81, 0, 160, 300, null, null],
|
||||||
|
[0, "만총", null, 0, null, 88, 64, 87, 0, 160, 300, null, null],
|
||||||
|
[0, "모개", null, 0, null, 63, 39, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "맹획", null, 0, null, 81, 88, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "맹체", null, 0, null, 75, 55, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "맹우", null, 0, null, 50, 68, 22, 0, 160, 300, null, null],
|
||||||
|
[0, "유섭", null, 0, null, 62, 79, 24, 0, 160, 300, null, null],
|
||||||
|
[0, "양부", null, 0, null, 62, 48, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "옹개", null, 0, null, 73, 75, 57, 0, 160, 300, null, null],
|
||||||
|
[0, "양의", null, 0, null, 68, 40, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "양호", null, 0, null, 94, 69, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "양홍", null, 0, null, 33, 15, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "양앙", null, 0, null, 68, 72, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "양추", null, 0, null, 52, 65, 40, 0, 160, 300, null, null],
|
||||||
|
[0, "양수", null, 0, null, 46, 23, 83, 0, 160, 300, null, null],
|
||||||
|
[0, "양추2", null, 0, null, 67, 64, 44, 0, 160, 300, null, null],
|
||||||
|
[0, "양송", null, 0, null, 17, 5, 28, 0, 160, 300, null, null],
|
||||||
|
[0, "양임", null, 0, null, 70, 78, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "양조", null, 0, null, 53, 61, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "양백", null, 0, null, 44, 45, 19, 0, 160, 300, null, null],
|
||||||
|
[0, "양부2", null, 0, null, 67, 50, 83, 0, 160, 300, null, null],
|
||||||
|
[0, "양봉", null, 0, null, 66, 65, 31, 0, 160, 300, null, null],
|
||||||
|
[0, "양봉2", null, 0, null, 54, 62, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "뇌동", null, 0, null, 69, 78, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "뇌박", null, 0, null, 62, 70, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "이이", null, 0, null, 63, 77, 19, 0, 160, 300, null, null],
|
||||||
|
[0, "이회", null, 0, null, 79, 58, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "이각", null, 0, null, 69, 72, 24, 0, 160, 300, null, null],
|
||||||
|
[0, "육항", null, 0, null, 94, 68, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "육적", null, 0, null, 20, 7, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "육손", null, 0, null, 95, 71, 96, 0, 160, 300, null, null],
|
||||||
|
[0, "이엄", null, 0, null, 83, 84, 63, 0, 160, 300, null, null],
|
||||||
|
[0, "이유", null, 0, null, 61, 26, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "이숙", null, 0, null, 46, 69, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "이통", null, 0, null, 73, 81, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "이전", null, 0, null, 78, 80, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "이풍", null, 0, null, 69, 74, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "유언", null, 0, null, 61, 38, 80, 0, 160, 300, null, null],
|
||||||
|
[0, "유괴", null, 0, null, 71, 73, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "유기", null, 0, null, 52, 12, 63, 0, 160, 300, null, null],
|
||||||
|
[0, "유우", null, 0, null, 62, 33, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "유훈", null, 0, null, 47, 63, 35, 0, 160, 300, null, null],
|
||||||
|
[0, "유현", null, 0, null, 54, 66, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "유순", null, 0, null, 63, 46, 28, 0, 160, 300, null, null],
|
||||||
|
[0, "유장", null, 0, null, 31, 5, 34, 0, 160, 300, null, null],
|
||||||
|
[0, "유심", null, 0, null, 60, 48, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "유선", null, 0, null, 3, 5, 9, 0, 160, 300, null, null],
|
||||||
|
[0, "유종", null, 0, null, 24, 22, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "유도", null, 0, null, 25, 23, 26, 0, 160, 300, null, null],
|
||||||
|
[0, "유파", null, 0, null, 29, 22, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "유반", null, 0, null, 69, 76, 47, 0, 160, 300, null, null],
|
||||||
|
[0, "유비", null, 0, null, 88, 78, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "유표", null, 0, null, 48, 31, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "유복", null, 0, null, 64, 49, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "유벽", null, 0, null, 70, 72, 47, 0, 160, 300, null, null],
|
||||||
|
[0, "유봉", null, 0, null, 75, 79, 44, 0, 160, 300, null, null],
|
||||||
|
[0, "유엽", null, 0, null, 56, 32, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "유요", null, 0, null, 62, 67, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "여위황", null, 0, null, 58, 63, 29, 0, 160, 300, null, null],
|
||||||
|
[0, "요화", null, 0, null, 73, 76, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "양흥", null, 0, null, 61, 65, 19, 0, 160, 300, null, null],
|
||||||
|
[0, "양습", null, 0, null, 73, 40, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "양서", null, 0, null, 56, 62, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "능조", null, 0, null, 75, 81, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "능통", null, 0, null, 83, 89, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "여개", null, 0, null, 53, 30, 67, 0, 160, 300, null, null],
|
||||||
|
[0, "여건", null, 0, null, 57, 70, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "여광", null, 0, null, 56, 70, 13, 0, 160, 300, null, null],
|
||||||
|
[0, "여상", null, 0, null, 54, 71, 12, 0, 160, 300, null, null],
|
||||||
|
[0, "여대", null, 0, null, 80, 71, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "여범", null, 0, null, 73, 54, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "여포", null, 0, null, 89, 100, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "여몽", null, 0, null, 91, 69, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "윤직", null, 0, null, 46, 42, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "냉포", null, 0, null, 71, 82, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "누규", null, 0, null, 52, 13, 87, 0, 160, 300, null, null],
|
||||||
|
[0, "노숙", null, 0, null, 89, 56, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "노식", null, 0, null, 86, 63, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "범강", null, 0, null, 49, 50, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "장달", null, 0, null, 43, 56, 34, 0, 160, 300, null, null],
|
||||||
|
[0, "규람", null, 0, null, 55, 70, 58, 0, 160, 300, null, null],
|
||||||
|
[0, "대원", null, 0, null, 38, 32, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "왕기", null, 0, null, 81, 64, 86, 0, 160, 300, null, null],
|
||||||
|
[0, "왕상", null, 0, null, 23, 19, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "왕돈", null, 0, null, 60, 66, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "악침", null, 0, null, 73, 75, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "하제", null, 0, null, 83, 61, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "환범", null, 0, null, 40, 11, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "견초", null, 0, null, 72, 79, 57, 0, 160, 300, null, null],
|
||||||
|
[0, "고당륭", null, 0, null, 35, 24, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "오찬", null, 0, null, 68, 41, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "호질", null, 0, null, 73, 46, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "오질", null, 0, null, 16, 29, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "호준", null, 0, null, 79, 76, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "고담", null, 0, null, 53, 23, 77, 0, 160, 300, null, null],
|
||||||
|
[0, "최림", null, 0, null, 32, 22, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "사마망", null, 0, null, 78, 58, 83, 0, 160, 300, null, null],
|
||||||
|
[0, "주이", null, 0, null, 70, 73, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "전단", null, 0, null, 67, 64, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "조우", null, 0, null, 50, 43, 37, 0, 160, 300, null, null],
|
||||||
|
[0, "조상", null, 0, null, 39, 33, 30, 0, 160, 300, null, null],
|
||||||
|
[0, "조방", null, 0, null, 20, 14, 27, 0, 160, 300, null, null],
|
||||||
|
[0, "태사향", null, 0, null, 57, 66, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "장휴", null, 0, null, 63, 27, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "장호", null, 0, null, 75, 74, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "조광", null, 0, null, 67, 71, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "장집", null, 0, null, 76, 29, 80, 0, 160, 300, null, null],
|
||||||
|
[0, "장승", null, 0, null, 77, 55, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "장소2", null, 0, null, 23, 56, 31, 0, 160, 300, null, null],
|
||||||
|
[0, "조통", null, 0, null, 68, 67, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "진표", null, 0, null, 66, 42, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "정무", null, 0, null, 56, 35, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "정봉2", null, 0, null, 66, 66, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "전만", null, 0, null, 51, 73, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "마균", null, 0, null, 22, 17, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "방회", null, 0, null, 69, 75, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "낙통", null, 0, null, 76, 58, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "육개", null, 0, null, 65, 61, 79, 0, 160, 300, null, null],
|
||||||
|
[0, "유찬", null, 0, null, 78, 81, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "유소", null, 0, null, 68, 53, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "요립", null, 0, null, 32, 15, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "여거", null, 0, null, 78, 51, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈첨", null, 0, null, 70, 57, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "손휴", null, 0, null, 57, 42, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "극정", null, 0, null, 42, 23, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "호분", null, 0, null, 71, 76, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "손량", null, 0, null, 32, 26, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "마막", null, 0, null, 34, 12, 44, 0, 160, 300, null, null],
|
||||||
|
[0, "손호", null, 0, null, 41, 73, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "조모", null, 0, null, 54, 61, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "조환", null, 0, null, 30, 28, 30, 0, 160, 300, null, null],
|
||||||
|
[0, "사마유", null, 0, null, 71, 54, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈상", null, 0, null, 64, 79, 62, 0, 160, 300, null, null],
|
||||||
|
[0, "손화", null, 0, null, 31, 39, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "염우", null, 0, null, 52, 61, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "왕경", null, 0, null, 67, 49, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "왕혼", null, 0, null, 74, 71, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "곽혁", null, 0, null, 33, 29, 70, 0, 160, 300, null, null],
|
||||||
|
[0, "가범", null, 0, null, 60, 50, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "서질", null, 0, null, 68, 83, 24, 0, 160, 300, null, null],
|
||||||
|
[0, "손준", null, 0, null, 64, 70, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "손침", null, 0, null, 58, 55, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "우사", null, 0, null, 61, 34, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "진건", null, 0, null, 72, 71, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "동궐", null, 0, null, 65, 59, 76, 0, 160, 300, null, null],
|
||||||
|
[0, "당자", null, 0, null, 61, 71, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "등충", null, 0, null, 76, 80, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "황숭", null, 0, null, 67, 50, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "화핵", null, 0, null, 20, 24, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "허의", null, 0, null, 51, 74, 15, 0, 160, 300, null, null],
|
||||||
|
[0, "송겸", null, 0, null, 66, 78, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "호제", null, 0, null, 57, 39, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "나헌", null, 0, null, 86, 62, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "노숙2", null, 0, null, 73, 53, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "구성", null, 0, null, 63, 70, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "어부라", null, 0, null, 72, 68, 21, 0, 160, 300, null, null],
|
||||||
|
[0, "아하소과", null, 0, null, 61, 76, 13, 0, 160, 300, null, null],
|
||||||
|
[0, "가비능", null, 0, null, 77, 69, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "구력거", null, 0, null, 80, 68, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "강단", null, 0, null, 65, 83, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "황란", null, 0, null, 63, 75, 44, 0, 160, 300, null, null],
|
||||||
|
[0, "호주천", null, 0, null, 70, 71, 40, 0, 160, 300, null, null],
|
||||||
|
[0, "종리목", null, 0, null, 84, 61, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈교", null, 0, null, 62, 27, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "답돈", null, 0, null, 84, 82, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "반임", null, 0, null, 66, 79, 38, 0, 160, 300, null, null],
|
||||||
|
[0, "보도근", null, 0, null, 64, 73, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "미당대왕", null, 0, null, 59, 69, 21, 0, 160, 300, null, null],
|
||||||
|
[0, "유표2", null, 0, null, 73, 74, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "루반", null, 0, null, 65, 76, 39, 0, 160, 300, null, null],
|
||||||
|
[0, "손관", null, 0, null, 72, 78, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "곽석", null, 0, null, 59, 71, 48, 0, 160, 300, null, null],
|
||||||
|
[0, "주조", null, 0, null, 63, 68, 26, 0, 160, 300, null, null],
|
||||||
|
[0, "장거", null, 0, null, 79, 75, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "장순", null, 0, null, 73, 81, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "철리길", null, 0, null, 77, 70, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "주삭", null, 0, null, 54, 60, 50, 0, 160, 300, null, null],
|
||||||
|
[0, "황월영", null, 0, null, 46, 33, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "채염", null, 0, null, 42, 26, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "소교", null, 0, null, 23, 15, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "신헌영", null, 0, null, 65, 35, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "손상향", null, 0, null, 72, 79, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "대교", null, 0, null, 22, 30, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "초선", null, 0, null, 12, 22, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "교모", null, 0, null, 54, 45, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "관구수", null, 0, null, 58, 62, 33, 0, 160, 300, null, null],
|
||||||
|
[0, "관구전", null, 0, null, 63, 47, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "원유", null, 0, null, 56, 40, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "왕광", null, 0, null, 65, 41, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "신창", null, 0, null, 50, 26, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "사마주", null, 0, null, 61, 40, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "양제", null, 0, null, 67, 49, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "성만", null, 0, null, 61, 68, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "오연", null, 0, null, 66, 73, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "맹충", null, 0, null, 47, 28, 72, 0, 160, 300, null, null],
|
||||||
|
[0, "잠혼", null, 0, null, 1, 1, 22, 0, 160, 300, null, null],
|
||||||
|
[0, "사정", null, 0, null, 64, 76, 34, 0, 160, 300, null, null],
|
||||||
|
[0, "심영", null, 0, null, 70, 77, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "도준", null, 0, null, 65, 66, 46, 0, 160, 300, null, null],
|
||||||
|
[0, "만욱", null, 0, null, 21, 25, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "오언", null, 0, null, 76, 81, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "위막", null, 0, null, 57, 62, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "시삭", null, 0, null, 38, 65, 47, 0, 160, 300, null, null],
|
||||||
|
[0, "전속", null, 0, null, 47, 60, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "장화", null, 0, null, 36, 27, 78, 0, 160, 300, null, null],
|
||||||
|
[0, "오거", null, 0, null, 49, 61, 23, 0, 160, 300, null, null],
|
||||||
|
[0, "추정", null, 0, null, 70, 46, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "장특", null, 0, null, 73, 54, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "곽마", null, 0, null, 68, 71, 47, 0, 160, 300, null, null],
|
||||||
|
[0, "석포", null, 0, null, 69, 71, 49, 0, 160, 300, null, null],
|
||||||
|
[0, "견홍", null, 0, null, 70, 74, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "한거자", null, 0, null, 51, 59, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "휴원진", null, 0, null, 52, 68, 45, 0, 160, 300, null, null],
|
||||||
|
[0, "곽원", null, 0, null, 66, 73, 36, 0, 160, 300, null, null],
|
||||||
|
[0, "계옹", null, 0, null, 63, 52, 33, 0, 160, 300, null, null],
|
||||||
|
[0, "이부", null, 0, null, 31, 36, 74, 0, 160, 300, null, null],
|
||||||
|
[0, "왕업", null, 0, null, 33, 6, 35, 0, 160, 300, null, null],
|
||||||
|
[0, "좌혁", null, 0, null, 62, 66, 51, 0, 160, 300, null, null],
|
||||||
|
[0, "화타", null, 0, null, 57, 25, 73, 0, 160, 300, null, null],
|
||||||
|
[0, "사마휘", null, 0, null, 55, 26, 82, 0, 160, 300, null, null],
|
||||||
|
[0, "우길", null, 0, null, 23, 15, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "헌제", null, 0, null, 22, 18, 68, 0, 160, 300, null, null],
|
||||||
|
[0, "백기", null, 0, null, 100, 88, 69, 0, 160, 300, null, null],
|
||||||
|
[0, "한신", null, 0, null, 100, 74, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "악비", null, 0, null, 99, 91, 71, 0, 160, 300, null, null],
|
||||||
|
[0, "항적", null, 0, null, 99, 100, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "악의", null, 0, null, 98, 75, 96, 0, 160, 300, null, null],
|
||||||
|
[0, "영정", null, 0, null, 97, 55, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "강상", null, 0, null, 94, 49, 100, 0, 160, 300, null, null],
|
||||||
|
[0, "전단2", null, 0, null, 96, 75, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "이목", null, 0, null, 96, 69, 88, 0, 160, 300, null, null],
|
||||||
|
[0, "염파", null, 0, null, 97, 96, 75, 0, 160, 300, null, null],
|
||||||
|
[0, "왕전", null, 0, null, 94, 64, 83, 0, 160, 300, null, null],
|
||||||
|
[0, "오기", null, 0, null, 94, 66, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "곽거병", null, 0, null, 93, 92, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "영포", null, 0, null, 82, 91, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "이신", null, 0, null, 81, 88, 63, 0, 160, 300, null, null],
|
||||||
|
[0, "몽념", null, 0, null, 87, 86, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "전기", null, 0, null, 80, 85, 44, 0, 160, 300, null, null],
|
||||||
|
[0, "극신", null, 0, null, 76, 83, 42, 0, 160, 300, null, null],
|
||||||
|
[0, "항연", null, 0, null, 89, 80, 61, 0, 160, 300, null, null],
|
||||||
|
[0, "인상여", null, 0, null, 69, 38, 96, 0, 160, 300, null, null],
|
||||||
|
[0, "장자방", null, 0, null, 72, 40, 100, 0, 160, 300, null, null],
|
||||||
|
[0, "관이오", null, 0, null, 85, 64, 99, 0, 160, 300, null, null],
|
||||||
|
[0, "손빈", null, 0, null, 83, 22, 98, 0, 160, 300, null, null],
|
||||||
|
[0, "소진", null, 0, null, 90, 47, 96, 0, 160, 300, null, null],
|
||||||
|
[0, "범증", null, 0, null, 68, 24, 94, 0, 160, 300, null, null],
|
||||||
|
[0, "장의2", null, 0, null, 75, 23, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "공구", null, 0, null, 68, 70, 91, 0, 160, 300, null, null],
|
||||||
|
[0, "소하", null, 0, null, 56, 27, 97, 0, 160, 300, null, null],
|
||||||
|
[0, "한비", null, 0, null, 49, 18, 97, 0, 160, 300, null, null],
|
||||||
|
[0, "이사", null, 0, null, 48, 24, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "전문", null, 0, null, 79, 67, 89, 0, 160, 300, null, null],
|
||||||
|
[0, "황헐", null, 0, null, 81, 68, 88, 0, 160, 300, null, null],
|
||||||
|
[0, "방난", null, 0, null, 88, 95, 66, 0, 160, 300, null, null],
|
||||||
|
[0, "개섭", null, 0, null, 43, 97, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "형가", null, 0, null, 42, 89, 43, 0, 160, 300, null, null],
|
||||||
|
[0, "유방", null, 0, null, 90, 66, 85, 0, 160, 300, null, null],
|
||||||
|
[0, "하리", null, 0, null, 95, 95, 65, 0, 160, 300, null, null],
|
||||||
|
[0, "헹이", null, 0, null, 95, 62, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "나나", null, 0, null, 91, 52, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "장임2", null, 0, null, 90, 92, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "하야미", null, 0, null, 92, 57, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "이시리스", null, 0, null, 93, 59, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "연채홍", null, 0, null, 91, 52, 91, 0, 160, 300, null, null],
|
||||||
|
[0, "임사영", null, 0, null, 40, 40, 40, 0, 160, 300, null, null],
|
||||||
|
[0, "장군보", null, 0, null, 90, 90, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "크렌스", null, 0, null, 91, 91, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "콘", null, 0, null, 91, 92, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "리즈나", null, 0, null, 90, 56, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "오티누스", null, 0, null, 92, 91, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "네시", null, 0, null, 91, 57, 93, 0, 160, 300, null, null, "안 자고 싸우면 이겨요"],
|
||||||
|
[0, "시뉴카린", null, 0, null, 95, 90, 52, 0, 160, 300, null, null, "피리피리~"],
|
||||||
|
[0, "Hide_D", null, 0, null, 92, 60, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "Pray", null, 0, null, 90, 92, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "사스케", null, 0, null, 91, 94, 54, 0, 160, 300, null, null],
|
||||||
|
[0, "SARS", null, 0, null, 91, 61, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "마요이", null, 0, null, 92, 53, 93, 0, 160, 300, null, null, "로열방 없습니다"],
|
||||||
|
[0, "세정", null, 0, null, 90, 92, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "김나영", null, 0, null, 93, 90, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "독구", null, 0, null, 95, 91, 62, 0, 160, 300, null, null, "웃자 ^-^"],
|
||||||
|
[0, "천괴금", null, 0, null, 33, 66, 99, 0, 160, 300, null, null],
|
||||||
|
[0, "관지평", null, 0, null, 90, 91, 52, 0, 160, 300, null, null, "농장팬티강도소녀!"],
|
||||||
|
[0, "모니카", null, 0, null, 90, 60, 93, 0, 160, 300, null, null, "론조.."],
|
||||||
|
[0, "카리야", null, 0, null, 93, 58, 95, 0, 160, 300, null, null, "깡!"],
|
||||||
|
[0, "rwitch", null, 0, null, 90, 52, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "카류", null, 0, null, 92, 53, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "갈근", null, 0, null, 94, 54, 94, 0, 160, 300, null, null],
|
||||||
|
[0, "페이트", null, 0, null, 92, 59, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "앵벌스", null, 0, null, 94, 91, 57, 0, 160, 300, null, null, "다람쥐는 위대하고 그 외에 다른 설치류는 없다"],
|
||||||
|
[0, "조밧", null, 0, null, 91, 93, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "슬라임", null, 0, null, 90, 56, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "제노에이지", null, 0, null, 93, 61, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "평민킬러", null, 0, null, 95, 92, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "아유", null, 0, null, 91, 54, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "로리", null, 0, null, 92, 55, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "n아텐 누", null, 0, null, 92, 55, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "Card", null, 0, null, 91, 90, 59, 0, 160, 300, null, null],
|
||||||
|
[0, "Per", null, 0, null, 93, 57, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "아쉐리트", null, 0, null, 94, 55, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "외심장", null, 0, null, 91, 57, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "카이스트", null, 0, null, 91, 53, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "아키라", null, 0, null, 80, 50, 80, 0, 160, 300, null, null, "뻐끔뻐끔"],
|
||||||
|
[0, "카오스피닉스", null, 0, null, 93, 58, 92, 0, 160, 300, null, null, "=ㅁ="],
|
||||||
|
[0, "민트토끼", null, 0, null, 92, 54, 90, 0, 160, 300, null, null, "나 바보 아니다!"],
|
||||||
|
[0, "くま", null, 0, null, 90, 92, 57, 0, 160, 300, null, null],
|
||||||
|
[0, "북오더", null, 0, null, 91, 58, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "이쓰미", null, 0, null, 92, 58, 91, 0, 160, 300, null, null],
|
||||||
|
[0, "개미호랑이", null, 0, null, 91, 55, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "수장", null, 0, null, 93, 57, 91, 0, 160, 300, null, null],
|
||||||
|
[0, "이드", null, 0, null, 92, 93, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "호무새", null, 0, null, 91, 53, 91, 0, 160, 300, null, null, "호우~"],
|
||||||
|
[0, "박일아", null, 0, null, 93, 59, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "유기체", null, 0, null, 92, 56, 95, 0, 160, 300, null, null, "흠... 그렇다면 어쩔 수 없이 흉노로 가야겠군요..."],
|
||||||
|
[0, "황약사", null, 0, null, 92, 92, 60, 0, 160, 300, null, null],
|
||||||
|
[0, "하후연묘재", null, 0, null, 92, 52, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "초절정미녀", null, 0, null, 95, 65, 95, 0, 160, 300, null, null],
|
||||||
|
[0, "제갈여포", null, 0, null, 92, 54, 91, 0, 160, 300, null, null],
|
||||||
|
[0, "온몸이근육", null, 0, null, 93, 93, 52, 0, 160, 300, null, null, "불끈불끈"],
|
||||||
|
[0, "네이미", null, 0, null, 91, 93, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "ARES군주", null, 0, null, 90, 93, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "중달", null, 0, null, 93, 92, 56, 0, 160, 300, null, null],
|
||||||
|
[0, "쿠레나이", null, 0, null, 90, 52, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "만샘", null, 0, null, 92, 55, 92, 0, 160, 300, null, null],
|
||||||
|
[0, "우돌", null, 0, null, 93, 91, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "아이린", null, 0, null, 93, 54, 90, 0, 160, 300, null, null],
|
||||||
|
[0, "유카", null, 0, null, 91, 92, 57, 0, 160, 300, null, null],
|
||||||
|
[0, "기", null, 0, null, 95, 90, 52, 0, 160, 300, null, null],
|
||||||
|
[0, "병리학적자세", null, 0, null, 91, 55, 93, 0, 160, 300, null, null],
|
||||||
|
[0, "료우기시키", null, 0, null, 92, 90, 53, 0, 160, 300, null, null],
|
||||||
|
[0, "Cure", null, 0, null, 92, 92, 55, 0, 160, 300, null, null],
|
||||||
|
[0, "40장로", null, 0, null, 85, 85, 85, 0, 160, 300, null, null]
|
||||||
|
],
|
||||||
|
"initialEvents":[
|
||||||
|
[
|
||||||
|
true,
|
||||||
|
["ChangeCity", "all", {
|
||||||
|
"trade":100
|
||||||
|
}]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"events":[
|
||||||
|
[
|
||||||
|
"month", 1000,
|
||||||
|
["Date", "==", 180, 1],
|
||||||
|
["ChangeCity", "all", {
|
||||||
|
"trade":100
|
||||||
|
}],
|
||||||
|
["DeleteEvent"]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"month", 1000,
|
||||||
|
["Date", "==", 180, 7],
|
||||||
|
["ChangeCity", "all", {
|
||||||
|
"trade":100
|
||||||
|
}],
|
||||||
|
["DeleteEvent"]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"month", 1000,
|
||||||
|
["Date", "==", 181, 1],
|
||||||
|
["ChangeCity", "all", {
|
||||||
|
"trade":100
|
||||||
|
}],
|
||||||
|
["DeleteEvent"]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"month", 1000,
|
||||||
|
["Date", "==", 181, 7],
|
||||||
|
["ChangeCity", "all", {
|
||||||
|
"trade":100
|
||||||
|
}],
|
||||||
|
["DeleteEvent"]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"month", 1000,
|
||||||
|
["Date", "==", 182, 1],
|
||||||
|
["ChangeCity", "all", {
|
||||||
|
"trade":100
|
||||||
|
}],
|
||||||
|
["DeleteEvent"]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"month", 1000,
|
||||||
|
["Date", "==", 182, 7],
|
||||||
|
["ChangeCity", "all", {
|
||||||
|
"trade":100
|
||||||
|
}],
|
||||||
|
["DeleteEvent"]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"destroy_nation", 1000,
|
||||||
|
["and",
|
||||||
|
["Date", ">=", 183, 1],
|
||||||
|
["RemainNation", "==", 1]
|
||||||
|
],
|
||||||
|
["BlockScoutAction"],
|
||||||
|
["DeleteEvent"]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
+761
-107
@@ -1,19 +1,27 @@
|
|||||||
{
|
{
|
||||||
"title":"【이벤트】 대리전",
|
"title": "【이벤트】 대리전",
|
||||||
"startYear":180,
|
"startYear": 180,
|
||||||
"map":{
|
"map": {
|
||||||
"mapName":"miniche_b"
|
"mapName": "miniche_b"
|
||||||
},
|
},
|
||||||
"history":[
|
"history": [
|
||||||
"<C>●</>180년 1월:<L><b>【이벤트】</b></>NPC 군주 뒤에 플레이해보는 이벤트 깃수"
|
"<C>●</>180년 1월:<L><b>【이벤트】</b></>NPC 군주 뒤에 플레이해보는 이벤트 깃수"
|
||||||
],
|
],
|
||||||
"const": {
|
"const": {
|
||||||
"joinRuinedNPCProp":0,
|
"joinRuinedNPCProp": 0,
|
||||||
"npcBanMessageProb":1,
|
"npcBanMessageProb": 1,
|
||||||
"availableGeneralCommand": {
|
"availableGeneralCommand": {
|
||||||
"": [
|
"개인": [
|
||||||
"휴식",
|
"휴식",
|
||||||
"che_요양"
|
"che_요양",
|
||||||
|
"che_단련",
|
||||||
|
"che_숙련전환",
|
||||||
|
"che_견문",
|
||||||
|
"che_은퇴",
|
||||||
|
"che_장비매매",
|
||||||
|
"che_군량매매",
|
||||||
|
"che_내정특기초기화",
|
||||||
|
"che_전투특기초기화"
|
||||||
],
|
],
|
||||||
"내정": [
|
"내정": [
|
||||||
"che_농지개간",
|
"che_농지개간",
|
||||||
@@ -27,36 +35,29 @@
|
|||||||
"che_물자조달"
|
"che_물자조달"
|
||||||
],
|
],
|
||||||
"군사": [
|
"군사": [
|
||||||
"che_소집해제",
|
|
||||||
"che_첩보",
|
|
||||||
"che_징병",
|
"che_징병",
|
||||||
"che_모병",
|
"che_모병",
|
||||||
"che_훈련",
|
"che_훈련",
|
||||||
"che_사기진작",
|
"che_사기진작",
|
||||||
"che_출병"
|
"che_출병",
|
||||||
|
"che_집합",
|
||||||
|
"che_소집해제",
|
||||||
|
"che_첩보"
|
||||||
],
|
],
|
||||||
"인사": [
|
"인사": [
|
||||||
"che_이동",
|
"che_이동",
|
||||||
"che_강행",
|
"che_강행",
|
||||||
"che_인재탐색",
|
"che_인재탐색",
|
||||||
"che_집합",
|
|
||||||
"che_귀환",
|
"che_귀환",
|
||||||
"che_랜덤임관"
|
"che_랜덤임관"
|
||||||
],
|
],
|
||||||
"계략": [
|
"계략": [
|
||||||
"che_화계",
|
"che_선동",
|
||||||
"che_파괴",
|
|
||||||
"che_탈취",
|
"che_탈취",
|
||||||
"che_선동"
|
"che_파괴",
|
||||||
|
"che_화계"
|
||||||
],
|
],
|
||||||
"개인": [
|
"국가": [
|
||||||
"che_내정특기초기화",
|
|
||||||
"che_전투특기초기화",
|
|
||||||
"che_단련",
|
|
||||||
"che_숙련전환",
|
|
||||||
"che_견문",
|
|
||||||
"che_장비매매",
|
|
||||||
"che_군량매매",
|
|
||||||
"che_증여",
|
"che_증여",
|
||||||
"che_헌납",
|
"che_헌납",
|
||||||
"che_하야"
|
"che_하야"
|
||||||
@@ -93,102 +94,755 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nation":[
|
"nation": [
|
||||||
["엄백호", "#800080", 10000, 10000, "엄백호", 500, "che_덕가", 1, ["건안"]],
|
[
|
||||||
["맹획", "#A0522D", 10000, 10000, "맹획", 500, "che_덕가", 1, ["월수"]],
|
"엄백호",
|
||||||
["유표", "#E0FFFF", 10000, 10000, "유표", 500, "che_도가", 1, ["영릉"]],
|
"#800080",
|
||||||
["올돌골", "#800000", 10000, 10000, "올돌골", 500, "che_도적", 1, ["남해"]],
|
10000,
|
||||||
["동탁", "#A9A9A9", 10000, 10000, "동탁", 500, "che_도적", 1, ["안정"]],
|
10000,
|
||||||
["유비", "#008000", 10000, 10000, "유비", 500, "che_명가", 1, ["평원"]],
|
"엄백호",
|
||||||
["유기", "#008080", 10000, 10000, "유기", 500, "che_명가", 1, ["강하"]],
|
500,
|
||||||
["유장", "#483D8B", 10000, 10000, "유장", 500, "che_묵가", 1, ["덕양"]],
|
"che_덕가",
|
||||||
["조조", "#000080", 10000, 10000, "조조", 500, "che_법가", 1, ["진류"]],
|
1,
|
||||||
["원소", "#FF00FF", 10000, 10000, "원소", 500, "che_병가", 1, ["거록"]],
|
[
|
||||||
["공손찬", "#87CEEB", 10000, 10000, "공손찬", 500, "che_병가", 1, ["계"]],
|
"건안"
|
||||||
["신라", "#FFA500", 10000, 10000, "신라", 500, "che_불가", 1, ["계림"]],
|
]
|
||||||
["고구려", "#FF6347", 10000, 10000, "고구려", 500, "che_불가", 1, ["국내"]],
|
],
|
||||||
["장로", "#20B2AA", 10000, 10000, "장로", 500, "che_오두미도", 1, ["상용"]],
|
[
|
||||||
["도겸", "#00FF00", 10000, 10000, "도겸", 500, "che_오두미도", 1, ["하비"]],
|
"맹획",
|
||||||
["손권", "#FF0000", 10000, 10000, "손권", 500, "che_유가", 1, ["오"]],
|
"#A0522D",
|
||||||
["헌제", "#BA55D3", 10000, 10000, "헌제", 500, "che_유가", 1, ["홍농"]],
|
10000,
|
||||||
["원술", "#FFC0CB", 10000, 10000, "원술", 500, "che_음양가", 1, ["여남"]],
|
10000,
|
||||||
["마등", "#808000", 10000, 10000, "마등", 500, "che_종횡가", 1, ["무도"]],
|
"맹획",
|
||||||
["목록대왕", "#7CFC00", 10000, 10000, "목록대왕", 500, "che_종횡가", 1, ["건녕"]],
|
500,
|
||||||
["장량", "#FFD700", 10000, 10000, "장량", 500, "che_태평도", 1, ["하내"]]
|
"che_덕가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"월수"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"유표",
|
||||||
|
"#E0FFFF",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"유표",
|
||||||
|
500,
|
||||||
|
"che_도가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"영릉"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"올돌골",
|
||||||
|
"#800000",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"올돌골",
|
||||||
|
500,
|
||||||
|
"che_도적",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"남해"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"동탁",
|
||||||
|
"#A9A9A9",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"동탁",
|
||||||
|
500,
|
||||||
|
"che_도적",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"안정"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"유비",
|
||||||
|
"#008000",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"유비",
|
||||||
|
500,
|
||||||
|
"che_명가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"평원"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"유기",
|
||||||
|
"#008080",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"유기",
|
||||||
|
500,
|
||||||
|
"che_명가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"강하"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"유장",
|
||||||
|
"#483D8B",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"유장",
|
||||||
|
500,
|
||||||
|
"che_묵가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"덕양"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"조조",
|
||||||
|
"#000080",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"조조",
|
||||||
|
500,
|
||||||
|
"che_법가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"진류"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"원소",
|
||||||
|
"#FF00FF",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"원소",
|
||||||
|
500,
|
||||||
|
"che_병가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"거록"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"공손찬",
|
||||||
|
"#87CEEB",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"공손찬",
|
||||||
|
500,
|
||||||
|
"che_병가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"계"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"신라",
|
||||||
|
"#FFA500",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"신라",
|
||||||
|
500,
|
||||||
|
"che_불가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"계림"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"고구려",
|
||||||
|
"#FF6347",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"고구려",
|
||||||
|
500,
|
||||||
|
"che_불가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"국내"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"장로",
|
||||||
|
"#20B2AA",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"장로",
|
||||||
|
500,
|
||||||
|
"che_오두미도",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"상용"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"도겸",
|
||||||
|
"#00FF00",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"도겸",
|
||||||
|
500,
|
||||||
|
"che_오두미도",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"하비"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"손권",
|
||||||
|
"#FF0000",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"손권",
|
||||||
|
500,
|
||||||
|
"che_유가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"오"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"헌제",
|
||||||
|
"#BA55D3",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"헌제",
|
||||||
|
500,
|
||||||
|
"che_유가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"홍농"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"원술",
|
||||||
|
"#FFC0CB",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"원술",
|
||||||
|
500,
|
||||||
|
"che_음양가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"여남"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"마등",
|
||||||
|
"#808000",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"마등",
|
||||||
|
500,
|
||||||
|
"che_종횡가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"무도"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"목록대왕",
|
||||||
|
"#7CFC00",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"목록대왕",
|
||||||
|
500,
|
||||||
|
"che_종횡가",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"건녕"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"장량",
|
||||||
|
"#FFD700",
|
||||||
|
10000,
|
||||||
|
10000,
|
||||||
|
"장량",
|
||||||
|
500,
|
||||||
|
"che_태평도",
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
"하내"
|
||||||
|
]
|
||||||
|
]
|
||||||
],
|
],
|
||||||
"general":[
|
"general": [
|
||||||
[999, "엄백호", 1217, 1, null, 85, 85, 85, 12, 150, 250, null, null],
|
[
|
||||||
[999, "맹획", 1108, 2, null, 85, 85, 85, 12, 150, 250, null, null],
|
999,
|
||||||
[999, "유표", 1293, 3, null, 85, 85, 85, 12, 150, 250, null, null],
|
"엄백호",
|
||||||
[999, "올돌골", 1241, 4, null, 85, 85, 85, 12, 150, 250, null, null],
|
1217,
|
||||||
[999, "동탁", 1083, 5, null, 85, 85, 85, 12, 150, 250, null, null],
|
1,
|
||||||
[999, "유비", 1281, 6, null, 85, 85, 85, 12, 150, 250, null, null],
|
null,
|
||||||
[999, "유기", 1276, 7, null, 85, 85, 85, 12, 150, 250, null, null],
|
85,
|
||||||
[999, "유장", 1290, 8, null, 85, 85, 85, 12, 150, 250, null, null],
|
85,
|
||||||
[999, "조조", 1392, 9, null, 85, 85, 85, 12, 150, 250, null, null],
|
85,
|
||||||
[999, "원소", 1268, 10, null, 85, 85, 85, 12, 150, 250, null, null],
|
12,
|
||||||
[999, "공손찬", 1033, 11, null, 85, 85, 85, 12, 150, 250, null, null],
|
150,
|
||||||
[999, "석벌휴", null, 12, null, 85, 85, 85, 12, 150, 250, null, null],
|
250,
|
||||||
[999, "고남무", null, 13, null, 85, 85, 85, 12, 150, 250, null, null],
|
null,
|
||||||
[999, "장로", 1319, 14, null, 85, 85, 85, 12, 150, 250, null, null],
|
null
|
||||||
[999, "도겸", 1074, 15, null, 85, 85, 85, 12, 150, 250, null, null],
|
],
|
||||||
[999, "손권", 1169, 16, null, 85, 85, 85, 12, 150, 250, null, null],
|
[
|
||||||
[999, "헌제", 1002, 17, null, 85, 85, 85, 12, 150, 250, null, null],
|
999,
|
||||||
[999, "원술", 1269, 18, null, 85, 85, 85, 12, 150, 250, null, null],
|
"맹획",
|
||||||
[999, "마등", 1094, 19, null, 85, 85, 85, 12, 150, 250, null, null],
|
1108,
|
||||||
[999, "목록대왕", 1110, 20, null, 85, 85, 85, 12, 150, 250, null, null],
|
2,
|
||||||
[999, "장량", 1318, 21, null, 85, 85, 85, 12, 150, 250, null, null]
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"유표",
|
||||||
|
1293,
|
||||||
|
3,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"올돌골",
|
||||||
|
1241,
|
||||||
|
4,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"동탁",
|
||||||
|
1083,
|
||||||
|
5,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"유비",
|
||||||
|
1281,
|
||||||
|
6,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"유기",
|
||||||
|
1276,
|
||||||
|
7,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"유장",
|
||||||
|
1290,
|
||||||
|
8,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"조조",
|
||||||
|
1392,
|
||||||
|
9,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"원소",
|
||||||
|
1268,
|
||||||
|
10,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"공손찬",
|
||||||
|
1033,
|
||||||
|
11,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"석벌휴",
|
||||||
|
null,
|
||||||
|
12,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"고남무",
|
||||||
|
null,
|
||||||
|
13,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"장로",
|
||||||
|
1319,
|
||||||
|
14,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"도겸",
|
||||||
|
1074,
|
||||||
|
15,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"손권",
|
||||||
|
1169,
|
||||||
|
16,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"헌제",
|
||||||
|
1002,
|
||||||
|
17,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"원술",
|
||||||
|
1269,
|
||||||
|
18,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"마등",
|
||||||
|
1094,
|
||||||
|
19,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"목록대왕",
|
||||||
|
1110,
|
||||||
|
20,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
],
|
||||||
|
[
|
||||||
|
999,
|
||||||
|
"장량",
|
||||||
|
1318,
|
||||||
|
21,
|
||||||
|
null,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
85,
|
||||||
|
12,
|
||||||
|
150,
|
||||||
|
250,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
]
|
||||||
],
|
],
|
||||||
"events":[
|
"events": [
|
||||||
[
|
[
|
||||||
"month", 1000,
|
"month",
|
||||||
["or", ["Date", "==", null, 12], ["Date", "==", null, 6]],
|
1000,
|
||||||
["CreateManyNPC", 10, 10],
|
[
|
||||||
["DeleteEvent"]
|
"or",
|
||||||
],
|
[
|
||||||
[
|
"Date",
|
||||||
"month", 1000,
|
"==",
|
||||||
["Date", "==", 181, 1],
|
null,
|
||||||
["OpenNationBetting", 4, 1000],
|
12
|
||||||
["OpenNationBetting", 1, 1000],
|
],
|
||||||
["DeleteEvent"]
|
[
|
||||||
],
|
"Date",
|
||||||
[
|
"==",
|
||||||
"month", 1000,
|
null,
|
||||||
["and",
|
6
|
||||||
["Date", ">=", 183, 1],
|
]
|
||||||
["RemainNation", "<=", 16]
|
|
||||||
],
|
],
|
||||||
["OpenNationBetting", 4, 1000],
|
[
|
||||||
["OpenNationBetting", 1, 1000],
|
"CreateManyNPC",
|
||||||
["DeleteEvent"]
|
10,
|
||||||
|
10
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"DeleteEvent"
|
||||||
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"month", 1000,
|
"month",
|
||||||
["and",
|
1000,
|
||||||
["Date", ">=", 183, 1],
|
[
|
||||||
["RemainNation", "<=", 8]
|
"Date",
|
||||||
|
"==",
|
||||||
|
181,
|
||||||
|
1
|
||||||
],
|
],
|
||||||
["OpenNationBetting", 1, 1000],
|
[
|
||||||
["DeleteEvent"]
|
"OpenNationBetting",
|
||||||
|
4,
|
||||||
|
1000
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"OpenNationBetting",
|
||||||
|
1,
|
||||||
|
1000
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"DeleteEvent"
|
||||||
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"month", 1000,
|
"month",
|
||||||
["and",
|
1000,
|
||||||
["Date", ">=", 183, 1],
|
[
|
||||||
["RemainNation", "<=", 4]
|
"and",
|
||||||
|
[
|
||||||
|
"Date",
|
||||||
|
">=",
|
||||||
|
183,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"RemainNation",
|
||||||
|
"<=",
|
||||||
|
16
|
||||||
|
]
|
||||||
],
|
],
|
||||||
["OpenNationBetting", 1, 1000],
|
[
|
||||||
["DeleteEvent"]
|
"OpenNationBetting",
|
||||||
|
4,
|
||||||
|
1000
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"OpenNationBetting",
|
||||||
|
1,
|
||||||
|
1000
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"DeleteEvent"
|
||||||
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"destroy_nation", 1000,
|
"month",
|
||||||
["and",
|
1000,
|
||||||
["Date", ">=", 183, 1],
|
[
|
||||||
["RemainNation", "==", 1]
|
"and",
|
||||||
|
[
|
||||||
|
"Date",
|
||||||
|
">=",
|
||||||
|
183,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"RemainNation",
|
||||||
|
"<=",
|
||||||
|
8
|
||||||
|
]
|
||||||
],
|
],
|
||||||
["BlockScoutAction"],
|
[
|
||||||
["DeleteEvent"]
|
"OpenNationBetting",
|
||||||
|
1,
|
||||||
|
1000
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"DeleteEvent"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"month",
|
||||||
|
1000,
|
||||||
|
[
|
||||||
|
"and",
|
||||||
|
[
|
||||||
|
"Date",
|
||||||
|
">=",
|
||||||
|
183,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"RemainNation",
|
||||||
|
"<=",
|
||||||
|
4
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"OpenNationBetting",
|
||||||
|
1,
|
||||||
|
1000
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"DeleteEvent"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"destroy_nation",
|
||||||
|
1000,
|
||||||
|
[
|
||||||
|
"and",
|
||||||
|
[
|
||||||
|
"Date",
|
||||||
|
">=",
|
||||||
|
183,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"RemainNation",
|
||||||
|
"==",
|
||||||
|
1
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"BlockScoutAction"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"DeleteEvent"
|
||||||
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -31,11 +31,16 @@ $modcolor2: color.adjust($nbase2color, $lightness: -5%);
|
|||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.time_pad.inverted{
|
||||||
|
background-color: gray;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
.turn_pad {
|
.turn_pad {
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row:nth-child(odd) .turn_pad {
|
.row:nth-of-type(odd) .turn_pad {
|
||||||
background-color: $modcolor2;
|
background-color: $modcolor2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,7 +88,7 @@ $modcolor2: color.adjust($nbase2color, $lightness: -5%);
|
|||||||
}
|
}
|
||||||
|
|
||||||
.commandBox .controlPad {
|
.commandBox .controlPad {
|
||||||
.turn_pad:nth-child(2n) {
|
.turn_pad:nth-of-type(even) {
|
||||||
background-color: $modcolor2;
|
background-color: $modcolor2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,7 +114,6 @@ $modcolor2: color.adjust($nbase2color, $lightness: -5%);
|
|||||||
width: 500px;
|
width: 500px;
|
||||||
height: 460px;
|
height: 460px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#mainTable {
|
#mainTable {
|
||||||
@@ -131,7 +135,7 @@ $modcolor2: color.adjust($nbase2color, $lightness: -5%);
|
|||||||
.commandBox .controlPad {
|
.commandBox .controlPad {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
|
||||||
.turn_pad:nth-child(even) {
|
.turn_pad:nth-of-type(even) {
|
||||||
background-color: $modcolor2;
|
background-color: $modcolor2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,7 +149,7 @@ $modcolor2: color.adjust($nbase2color, $lightness: -5%);
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
|
||||||
.turn_pad:nth-child(even) {
|
.turn_pad:nth-of-type(even) {
|
||||||
background-color: $modcolor2;
|
background-color: $modcolor2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
@import '@scss/common/bootstrap5.scss';
|
||||||
|
@import "@scss/game_bg.scss";
|
||||||
|
@import "@scss/util.scss";
|
||||||
|
|
||||||
|
#container{
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@include media-1000px {
|
||||||
|
#container {
|
||||||
|
width: 1000px;
|
||||||
|
margin: 0 auto;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-500px {
|
||||||
|
#container {
|
||||||
|
position: relative;
|
||||||
|
width: 500px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<tr
|
<tr
|
||||||
data-is-our-general="<?=$ourGeneral?'true':'false'?>"
|
data-is-our-general="<?=$ourGeneral?'true':'false'?>"
|
||||||
data-is-npc="<?=$isNPC?'true':'false'?>"
|
data-is-npc="<?=$isNPC?'true':'false'?>"
|
||||||
|
data-npc-type="<?=$npc?>"
|
||||||
data-general-wounded="<?=$wounded?>"
|
data-general-wounded="<?=$wounded?>"
|
||||||
data-general-name="<?=$this->e($name)?>"
|
data-general-name="<?=$this->e($name)?>"
|
||||||
data-general-leadership="<?=$leadership?>"
|
data-general-leadership="<?=$leadership?>"
|
||||||
@@ -33,7 +34,7 @@
|
|||||||
<td><?=$train?></td>
|
<td><?=$train?></td>
|
||||||
<td><?=$atmos?></td>
|
<td><?=$atmos?></td>
|
||||||
<?php if($isNPC): ?>
|
<?php if($isNPC): ?>
|
||||||
<td>NPC 장수</td>
|
<td>NPC 장수</td>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<td class="general_turn_text"><?=$turnText?></td>
|
<td class="general_turn_text"><?=$turnText?></td>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
@@ -49,5 +50,5 @@
|
|||||||
<td>재 야</td>
|
<td>재 야</td>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
<?=$btnBegin??''?><a href='b_tournament.php' target='_blank' class='open-window <?=$btnClassForTournament??""?>'>토 너 먼 트</a><?=$btnEnd??''?>
|
<?=$btnBegin??''?><a href='b_tournament.php' target='_blank' class='open-window <?=$btnClassForTournament??""?>'>토 너 먼 트</a><?=$btnEnd??''?>
|
||||||
<?=$btnBegin??''?><a href='b_myKingdomInfo.php' class='commandButton <?=$btnClass??""?> <?= $meLevel >= 1 ? '' : 'disabled' ?>'>세력 정보</a><?=$btnEnd??''?>
|
<?=$btnBegin??''?><a href='b_myKingdomInfo.php' class='commandButton <?=$btnClass??""?> <?= $meLevel >= 1 ? '' : 'disabled' ?>'>세력 정보</a><?=$btnEnd??''?>
|
||||||
<?=$btnBegin??''?><a href='b_myCityInfo.php' class='commandButton <?=$btnClass??""?> <?= ($meLevel >= 1 && $nationLevel >= 1) ? '' : 'disabled' ?>'>세력 도시</a><?=$btnEnd??''?>
|
<?=$btnBegin??''?><a href='b_myCityInfo.php' class='commandButton <?=$btnClass??""?> <?= ($meLevel >= 1 && $nationLevel >= 1) ? '' : 'disabled' ?>'>세력 도시</a><?=$btnEnd??''?>
|
||||||
<?=$btnBegin??''?><a href='b_myGenInfo.php' class='commandButton <?=$btnClass??""?> <?= $meLevel >= 1 ? '' : 'disabled' ?>'>세력 장수</a><?=$btnEnd??''?>
|
<?=$btnBegin??''?><a href='v_nationGeneral.php' class='commandButton <?=$btnClass??""?> <?= $meLevel >= 1 ? '' : 'disabled' ?>'>세력 장수</a><?=$btnEnd??''?>
|
||||||
<?=$btnBegin??''?><a href='b_diplomacy.php' class='commandButton <?=$btnClass??""?>'>중원 정보</a><?=$btnEnd??''?>
|
<?=$btnBegin??''?><a href='b_diplomacy.php' class='commandButton <?=$btnClass??""?>'>중원 정보</a><?=$btnEnd??''?>
|
||||||
<?=$btnBegin??''?><a href='b_currentCity.php' class='commandButton <?=$btnClass??""?>'>현재 도시</a><?=$btnEnd??''?>
|
<?=$btnBegin??''?><a href='b_currentCity.php' class='commandButton <?=$btnClass??""?>'>현재 도시</a><?=$btnEnd??''?>
|
||||||
<?=$btnBegin??''?><a href='b_battleCenter.php' target='_blank' class='open-window commandButton <?=$btnClass??""?> <?= $showSecret ? '' : 'disabled' ?>'>감 찰 부</a><?=$btnEnd??''?>
|
<?=$btnBegin??''?><a href='b_battleCenter.php' target='_blank' class='open-window commandButton <?=$btnClass??""?> <?= $showSecret ? '' : 'disabled' ?>'>감 찰 부</a><?=$btnEnd??''?>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
<tr class='general_id_<?=$general['no']?>'
|
<tr class='general_id_<?=$general['no']?>'
|
||||||
data-general-id="<?=$general['no']?>"
|
data-general-id="<?=$general['no']?>"
|
||||||
data-is-npc="<?=$general['npc']>=2?'true':'false'?>"
|
data-is-npc="<?=$general['npc']>=2?'true':'false'?>"
|
||||||
|
data-npc-type='<?=$general['npc']?>'
|
||||||
data-general-wounded="<?=$general['injury']?>"
|
data-general-wounded="<?=$general['injury']?>"
|
||||||
data-general-name="<?=$general['name']?>"
|
data-general-name="<?=$general['name']?>"
|
||||||
data-general-leadership="<?=$general['leadership']?>"
|
data-general-leadership="<?=$general['leadership']?>"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div class="world_map map_theme_<?= $mapTheme ?> draw_required">
|
<div class="world_map map_theme_<?= $mapName ?> draw_required">
|
||||||
<div class="map_title obj_tooltip" data-bs-toggle="tooltip" data-bs-placement="top" data-tooltip-class="map_title_tooltiptext">
|
<div class="map_title obj_tooltip" data-bs-toggle="tooltip" data-bs-placement="top" data-tooltip-class="map_title_tooltiptext">
|
||||||
<span class="map_title_text ">
|
<span class="map_title_text ">
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
|
v-for="(officer, _idx) in [chiefList[chiefLevel]]"
|
||||||
|
:key="_idx"
|
||||||
:class="[`chiefBox${chiefLevel}`, 'subRows']"
|
:class="[`chiefBox${chiefLevel}`, 'subRows']"
|
||||||
v-for="(officer, idx) in [chiefList[chiefLevel]]"
|
|
||||||
:key="idx"
|
|
||||||
:style="style"
|
:style="style"
|
||||||
@click="$emit('click', this)"
|
@click="$emit('click', this)"
|
||||||
>
|
>
|
||||||
@@ -13,21 +13,22 @@
|
|||||||
textDecoration: isMe ? 'underline' : undefined,
|
textDecoration: isMe ? 'underline' : undefined,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ officer?(officer?.name ?? "-"):'' }}
|
{{ officer ? officer?.name ?? "-" : "" }}
|
||||||
</div>
|
</div>
|
||||||
<div class="bg1 center row gx-0">
|
<div class="bg1 center row gx-0">
|
||||||
<div class="col">{{ officer?.officerLevelText }}</div>
|
<div class="col">
|
||||||
<div class="col">{{ officer?((officer?.turnTime ?? " - ").slice(-5)):'' }}</div>
|
{{ officer?.officerLevelText }}
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
{{ officer ? (officer?.turnTime ?? " - ").slice(-5) : "" }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="tableCell align-self-center turn_pad"
|
v-for="(turn, idx) in officer?.turn ?? []"
|
||||||
v-for="(turn, idx) in officer?.turn??[]"
|
|
||||||
:key="idx"
|
:key="idx"
|
||||||
|
class="tableCell align-self-center turn_pad"
|
||||||
:style="{
|
:style="{
|
||||||
fontSize:
|
fontSize: mb_strwidth(turn.brief) > 28 ? `${28 / mb_strwidth(turn.brief)}em` : undefined,
|
||||||
mb_strwidth(turn.brief) > 28
|
|
||||||
? `${28 / mb_strwidth(turn.brief)}em`
|
|
||||||
: undefined,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ turn.brief }}
|
{{ turn.brief }}
|
||||||
|
|||||||
+162
-72
@@ -1,88 +1,178 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="['subRows', 'chiefCommand']" :style="style">
|
<div style="position: relative">
|
||||||
<div class="bg1 center row gx-0" style="font-size: 1.2em">
|
<DragSelect
|
||||||
<div class="col-5 align-self-center text-end">
|
v-slot="{ selected }"
|
||||||
{{ officer ? `${officer.officerLevelText} : ` : "" }}
|
:class="['subRows', 'chiefCommand']"
|
||||||
|
:style="style"
|
||||||
|
:disabled="!props.officer || !isEditMode"
|
||||||
|
attribute="turnIdx"
|
||||||
|
@dragStart="dragStart()"
|
||||||
|
@dragDone="dragDone(...$event)"
|
||||||
|
>
|
||||||
|
<div class="bg1 center row gx-0" style="font-size: 1.2em">
|
||||||
|
<div class="col-5 align-self-center text-end">
|
||||||
|
{{ officer ? `${officer.officerLevelText} : ` : "" }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="col-7 align-self-center"
|
||||||
|
:style="{
|
||||||
|
color: getNpcColor(officer?.npcType ?? 0),
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ officer?.name }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-for="vidx in maxTurn" :key="vidx" :turnIdx="vidx" class="row c-bg2 gx-0">
|
||||||
class="col-7 align-self-center"
|
<div
|
||||||
:style="{
|
:class="[
|
||||||
color: getNpcColor(officer?.npcType ?? 0),
|
'col-2',
|
||||||
}"
|
'time_pad',
|
||||||
>
|
'f_tnum',
|
||||||
{{ officer?.name }}
|
(isDragToggle || isCopyButtonShown) && selected.has(vidx.toString()) ? 'inverted' : undefined,
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
{{ turnTimes[vidx - 1] }}
|
||||||
|
</div>
|
||||||
|
<div v-if="!officer || !officer.turn || !(vidx - 1 in officer.turn)" class="center" />
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="tableCell align-self-center col-10 center turn_pad"
|
||||||
|
:style="{
|
||||||
|
fontSize:
|
||||||
|
mb_strwidth(officer.turn[vidx - 1].brief) > 28
|
||||||
|
? `${28 / mb_strwidth(officer.turn[vidx - 1].brief)}em`
|
||||||
|
: undefined,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ officer.turn[vidx - 1].brief }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</DragSelect>
|
||||||
<div class="row c-bg2 gx-0" v-for="vidx in maxTurn" :key="vidx">
|
<BButton
|
||||||
<div class="col-2 time_pad f_tnum">
|
ref="btnCopy"
|
||||||
{{ turnTimes[vidx - 1] }}
|
:style="{
|
||||||
</div>
|
position: 'absolute',
|
||||||
<div
|
display: isCopyButtonShown ? 'block' : 'none',
|
||||||
class="center"
|
top: `${btnPos * 30 + 25}px`,
|
||||||
v-if="!officer || (!officer.turn) || !(vidx - 1 in officer.turn)"
|
right: '10px',
|
||||||
></div>
|
}"
|
||||||
<div
|
@blur="isCopyButtonShown = false"
|
||||||
v-else
|
@click="tryCopy()"
|
||||||
class="tableCell align-self-center col-10 center turn_pad"
|
>
|
||||||
:style="{
|
복사하기
|
||||||
fontSize:
|
</BButton>
|
||||||
mb_strwidth(officer.turn[vidx - 1].brief) > 28
|
|
||||||
? `${28 / mb_strwidth(officer.turn[vidx - 1].brief)}em`
|
|
||||||
: undefined,
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
{{ officer.turn[vidx - 1].brief }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { getNpcColor } from "@/common_legacy";
|
import { getNpcColor } from "@/common_legacy";
|
||||||
import { ChiefResponse } from "@/defs";
|
|
||||||
import { formatTime } from "@/util/formatTime";
|
import { formatTime } from "@/util/formatTime";
|
||||||
import { mb_strwidth } from "@/util/mb_strwidth";
|
import { mb_strwidth } from "@/util/mb_strwidth";
|
||||||
import { parseTime } from "@/util/parseTime";
|
import { parseTime } from "@/util/parseTime";
|
||||||
|
import type { StoredActionsHelper } from "@/util/StoredActionsHelper";
|
||||||
import addMinutes from "date-fns/esm/addMinutes/index";
|
import addMinutes from "date-fns/esm/addMinutes/index";
|
||||||
import { range } from "lodash";
|
import { range } from "lodash";
|
||||||
import { defineComponent, PropType } from "vue";
|
import { inject, onMounted, ref, type PropType } from "vue";
|
||||||
import VueTypes from "vue-types";
|
import VueTypes from "vue-types";
|
||||||
|
import DragSelect from "@/components/DragSelect.vue";
|
||||||
|
import { BButton } from "bootstrap-vue-3";
|
||||||
|
import { QueryActionHelper } from "@/util/QueryActionHelper";
|
||||||
|
import type { ChiefResponse } from "@/defs/API/NationCommand";
|
||||||
|
|
||||||
export default defineComponent({
|
const props = defineProps({
|
||||||
props: {
|
style: VueTypes.object.isRequired,
|
||||||
style: VueTypes.object.isRequired,
|
officer: {
|
||||||
officer: {
|
type: Object as PropType<ChiefResponse["chiefList"][0]>,
|
||||||
type: Object as PropType<ChiefResponse["chiefList"][0]>,
|
default: undefined,
|
||||||
},
|
|
||||||
turnTerm: VueTypes.integer.isRequired,
|
|
||||||
maxTurn: VueTypes.integer.isRequired,
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getNpcColor,
|
|
||||||
mb_strwidth,
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
const turnTimes: string[] = [];
|
|
||||||
if (!this.officer || !this.officer.turnTime) {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
for (const _ of range(this.maxTurn)) {
|
|
||||||
turnTimes.push("\xa0");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const baseTurnTime = parseTime(this.officer.turnTime);
|
|
||||||
for (const idx of range(this.officer.turn.length)) {
|
|
||||||
turnTimes.push(
|
|
||||||
formatTime(
|
|
||||||
addMinutes(baseTurnTime, idx * this.turnTerm),
|
|
||||||
this.turnTerm >= 5 ? "HH:mm" : "mm:ss"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
turnTimes,
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
|
turnTerm: VueTypes.integer.isRequired,
|
||||||
|
maxTurn: VueTypes.integer.isRequired,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const btnPos = ref(0);
|
||||||
|
const btnCopy = ref<InstanceType<typeof BButton> | null>(null);
|
||||||
|
|
||||||
|
const storedActionsHelper = inject<StoredActionsHelper>("storedNationActionsHelper");
|
||||||
|
const isEditMode = storedActionsHelper?.isEditMode ?? ref(false);
|
||||||
|
const isDragToggle = ref(false);
|
||||||
|
|
||||||
|
const isCopyButtonShown = ref(false);
|
||||||
|
|
||||||
|
const queryActionHelper = new QueryActionHelper(props.maxTurn);
|
||||||
|
const selectedTurnList = queryActionHelper.selectedTurnList;
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.officer === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
queryActionHelper.reservedCommandList.value = props.officer.turn.map((rawTurn) => {
|
||||||
|
return {
|
||||||
|
...rawTurn,
|
||||||
|
time: "",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
console.log(queryActionHelper.reservedCommandList.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
function dragStart() {
|
||||||
|
isDragToggle.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function eqSet<T>(as: Set<T>, bs: Set<T>) {
|
||||||
|
if (as.size !== bs.size) return false;
|
||||||
|
for (var a of as) if (!bs.has(a)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragDone(...rawSelectedTurn: string[]) {
|
||||||
|
if (rawSelectedTurn.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const newSelectedTurnList = new Set<number>();
|
||||||
|
|
||||||
|
let maxPos = -1;
|
||||||
|
for (const rawIdx of rawSelectedTurn) {
|
||||||
|
const idx = parseInt(rawIdx) - 1;
|
||||||
|
newSelectedTurnList.add(idx);
|
||||||
|
maxPos = Math.max(maxPos, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
btnPos.value = maxPos;
|
||||||
|
|
||||||
|
isDragToggle.value = false;
|
||||||
|
if (newSelectedTurnList.size == 1 && eqSet(selectedTurnList.value, newSelectedTurnList)) {
|
||||||
|
isCopyButtonShown.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selectedTurnList.value = newSelectedTurnList;
|
||||||
|
isCopyButtonShown.value = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
(btnCopy.value?.$el as HTMLButtonElement).focus();
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function tryCopy() {
|
||||||
|
const actions = queryActionHelper.extractQueryActions();
|
||||||
|
isCopyButtonShown.value = false;
|
||||||
|
|
||||||
|
if (!storedActionsHelper) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
storedActionsHelper.clipboard.value = [...actions];
|
||||||
|
}
|
||||||
|
|
||||||
|
const turnTimes = ref<string[]>([]);
|
||||||
|
|
||||||
|
if (!props.officer || !props.officer.turnTime) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
for (const _ of range(props.maxTurn)) {
|
||||||
|
turnTimes.value.push("\xa0");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const baseTurnTime = parseTime(props.officer.turnTime);
|
||||||
|
for (const idx of range(props.officer.turn.length)) {
|
||||||
|
turnTimes.value.push(
|
||||||
|
formatTime(addMinutes(baseTurnTime, idx * props.turnTerm), props.turnTerm >= 5 ? "HH:mm" : "mm:ss")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import { SammoAPI } from './SammoAPI';
|
||||||
|
import type { GetConstResponse } from './defs/API/Global';
|
||||||
|
import type { CityID, CrewTypeID, GameCityDefault, GameConstType, GameUnitType, GameIActionCategory, GameIActionKey, GameIActionInfo } from './defs/GameObj';
|
||||||
|
|
||||||
|
export class GameConstStore {
|
||||||
|
public readonly gameConst: GameConstType;
|
||||||
|
public readonly gameUnitConst: Record<CrewTypeID, GameUnitType>;
|
||||||
|
public readonly cityConst: Record<CityID, GameCityDefault>;
|
||||||
|
public readonly cityConstMap: {
|
||||||
|
region: Record<number | string, string | number>;
|
||||||
|
level: Record<number | string, string | number>; //defs.CityLevelText
|
||||||
|
};
|
||||||
|
public readonly iActionInfo: Record<
|
||||||
|
GameIActionCategory,
|
||||||
|
Record<
|
||||||
|
GameIActionKey,
|
||||||
|
GameIActionInfo
|
||||||
|
>
|
||||||
|
>;
|
||||||
|
public readonly iActionKeyMap: Record<string, GameIActionCategory>;
|
||||||
|
|
||||||
|
constructor(response: GetConstResponse) {
|
||||||
|
const data = response.data;
|
||||||
|
this.gameConst = Object.freeze(data.gameConst);
|
||||||
|
this.gameUnitConst = Object.freeze(data.gameUnitConst);
|
||||||
|
this.cityConst = Object.freeze(data.cityConst);
|
||||||
|
this.cityConstMap = Object.freeze(data.cityConstMap);
|
||||||
|
this.iActionInfo = Object.freeze(data.iActionInfo);
|
||||||
|
this.iActionKeyMap = Object.freeze(data.iActionKeyMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let gameConstStore: GameConstStore | undefined = undefined;
|
||||||
|
|
||||||
|
export async function getGameConstStore(): Promise<GameConstStore> {
|
||||||
|
//TODO: LocalStorage Cache 조합도 생각해보기.
|
||||||
|
if (gameConstStore !== undefined) {
|
||||||
|
return gameConstStore;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const result = await SammoAPI.Global.GetConst();
|
||||||
|
gameConstStore = new GameConstStore(result);
|
||||||
|
}
|
||||||
|
catch (e: unknown) {
|
||||||
|
console.error(`FATAL!: GameConst를 가져오지 못함: ${e}`);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return gameConstStore;
|
||||||
|
}
|
||||||
+51
-57
@@ -7,29 +7,23 @@
|
|||||||
<div class="row gx-0">
|
<div class="row gx-0">
|
||||||
<div class="col-2 col-md-1 articleTitle bg1 center">제목</div>
|
<div class="col-2 col-md-1 articleTitle bg1 center">제목</div>
|
||||||
<div class="col-10 col-md-11">
|
<div class="col-10 col-md-11">
|
||||||
<input
|
<input v-model="newArticle.title" class="titleInput" type="text" maxlength="250" placeholder="제목" />
|
||||||
class="titleInput"
|
|
||||||
type="text"
|
|
||||||
maxlength="250"
|
|
||||||
placeholder="제목"
|
|
||||||
v-model="newArticle.title"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row gx-0">
|
<div class="row gx-0">
|
||||||
<div class="col-2 col-md-1 bg1 center">내용</div>
|
<div class="col-2 col-md-1 bg1 center">내용</div>
|
||||||
<div class="col-10 col-md-11">
|
<div class="col-10 col-md-11">
|
||||||
<textarea
|
<textarea
|
||||||
class="contentInput autosize"
|
|
||||||
ref="newArticleTextForm"
|
ref="newArticleTextForm"
|
||||||
placeholder="내용"
|
|
||||||
v-model="newArticle.text"
|
v-model="newArticle.text"
|
||||||
|
class="contentInput autosize"
|
||||||
|
placeholder="내용"
|
||||||
@input="autoResizeTextarea"
|
@input="autoResizeTextarea"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-8 col-md-10"></div>
|
<div class="col-8 col-md-10" />
|
||||||
<div class="col-4 col-md-2 d-grid">
|
<div class="col-4 col-md-2 d-grid">
|
||||||
<b-button id="submitArticle" @click="submitArticle"> 등록 </b-button>
|
<b-button id="submitArticle" @click="submitArticle"> 등록 </b-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -41,13 +35,13 @@
|
|||||||
v-for="article in articles"
|
v-for="article in articles"
|
||||||
:key="article.no"
|
:key="article.no"
|
||||||
:article="article"
|
:article="article"
|
||||||
@submit-comment="reloadArticles"
|
@submitComment="reloadArticles"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-else> 게시물이 없습니다. </template>
|
<template v-else> 게시물이 없습니다. </template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<BottomBar/>
|
<BottomBar />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -58,7 +52,7 @@ import BottomBar from "@/components/BottomBar.vue";
|
|||||||
import BoardArticle from "@/components/BoardArticle.vue";
|
import BoardArticle from "@/components/BoardArticle.vue";
|
||||||
import { convertFormData } from "@util/convertFormData";
|
import { convertFormData } from "@util/convertFormData";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { InvalidResponse } from "@/defs";
|
import type { InvalidResponse } from "@/defs";
|
||||||
import { autoResizeTextarea } from "@util/autoResizeTextarea";
|
import { autoResizeTextarea } from "@util/autoResizeTextarea";
|
||||||
import { unwrap } from "@util/unwrap";
|
import { unwrap } from "@util/unwrap";
|
||||||
export type BoardResponse = {
|
export type BoardResponse = {
|
||||||
@@ -103,6 +97,49 @@ export default defineComponent({
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setup(props) {
|
||||||
|
const newArticleTextForm = ref<HTMLInputElement>();
|
||||||
|
const articles = reactive<BoardArticleItem[]>([]);
|
||||||
|
|
||||||
|
const reloadArticles = async () => {
|
||||||
|
let boardResponse: BoardResponse;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios({
|
||||||
|
url: "j_board_get_articles.php",
|
||||||
|
responseType: "json",
|
||||||
|
method: "post",
|
||||||
|
data: convertFormData({
|
||||||
|
isSecret: props.isSecretBoard,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
const result: InvalidResponse | BoardResponse = response.data;
|
||||||
|
if (!result.result) {
|
||||||
|
throw result.reason;
|
||||||
|
}
|
||||||
|
boardResponse = result;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
alert(`에러: ${e}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
articles.length = 0;
|
||||||
|
articles.push(...Object.values(boardResponse.articles));
|
||||||
|
articles.reverse();
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await reloadArticles();
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
newArticleTextForm,
|
||||||
|
articles,
|
||||||
|
reloadArticles,
|
||||||
|
};
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
title: this.isSecretBoard ? "기밀실" : "회의실",
|
title: this.isSecretBoard ? "기밀실" : "회의실",
|
||||||
@@ -150,48 +187,5 @@ export default defineComponent({
|
|||||||
await this.reloadArticles();
|
await this.reloadArticles();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
setup(props) {
|
|
||||||
const newArticleTextForm = ref<HTMLInputElement>();
|
|
||||||
const articles = reactive<BoardArticleItem[]>([]);
|
|
||||||
|
|
||||||
const reloadArticles = async () => {
|
|
||||||
let boardResponse: BoardResponse;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await axios({
|
|
||||||
url: "j_board_get_articles.php",
|
|
||||||
responseType: "json",
|
|
||||||
method: "post",
|
|
||||||
data: convertFormData({
|
|
||||||
isSecret: props.isSecretBoard,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
const result: InvalidResponse | BoardResponse = response.data;
|
|
||||||
if (!result.result) {
|
|
||||||
throw result.reason;
|
|
||||||
}
|
|
||||||
boardResponse = result;
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
alert(`에러: ${e}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
articles.length = 0;
|
|
||||||
articles.push(...Object.values(boardResponse.articles));
|
|
||||||
articles.reverse();
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
await reloadArticles();
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
newArticleTextForm,
|
|
||||||
articles,
|
|
||||||
reloadArticles,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
+133
-413
@@ -2,29 +2,12 @@
|
|||||||
<div id="container" class="pageChiefCenter">
|
<div id="container" class="pageChiefCenter">
|
||||||
<TopBackBar title="사령부" reloadable @reload="reloadTable" />
|
<TopBackBar title="사령부" reloadable @reload="reloadTable" />
|
||||||
|
|
||||||
<div
|
<div v-if="chiefList !== undefined" id="mainTable" :class="`${targetIsMe ? 'targetIsMe' : 'targetIsNotMe'}`">
|
||||||
id="mainTable"
|
<template v-for="(chiefLevel, vidx) in [12, 10, 8, 6, 11, 9, 7, 5]" :key="chiefLevel">
|
||||||
v-if="chiefList !== undefined"
|
<div v-if="vidx % 4 == 0" :class="['turnIdx', vidx == 0 && !targetIsMe ? undefined : 'only1000px']">
|
||||||
:class="`${targetIsMe ? 'targetIsMe' : 'targetIsNotMe'}`"
|
|
||||||
>
|
|
||||||
<template
|
|
||||||
v-for="(chiefLevel, vidx) in [12, 10, 8, 6, 11, 9, 7, 5]"
|
|
||||||
:key="chiefLevel"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-if="vidx % 4 == 0"
|
|
||||||
:class="[
|
|
||||||
'turnIdx',
|
|
||||||
vidx == 0 && !targetIsMe ? undefined : 'only1000px',
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<div :class="['subRows', 'bg0']" :style="mainTableGridRows">
|
<div :class="['subRows', 'bg0']" :style="mainTableGridRows">
|
||||||
<div class="bg1"> </div>
|
<div class="bg1"> </div>
|
||||||
<div
|
<div v-for="idx in maxChiefTurn" :key="idx" :class="[`turnIdxLeft`, 'align-self-center', 'center']">
|
||||||
v-for="idx in maxChiefTurn"
|
|
||||||
:class="[`turnIdxLeft`, 'align-self-center', 'center']"
|
|
||||||
:key="idx"
|
|
||||||
>
|
|
||||||
{{ idx }}
|
{{ idx }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -41,152 +24,27 @@
|
|||||||
:maxTurn="maxChiefTurn"
|
:maxTurn="maxChiefTurn"
|
||||||
:turnTerm="turnTerm"
|
:turnTerm="turnTerm"
|
||||||
/>
|
/>
|
||||||
<div class="commandBox" v-else>
|
<ChiefReservedCommand
|
||||||
<div
|
v-else
|
||||||
class="only1000px bg1 center row gx-0"
|
:key="idx"
|
||||||
style="height: 24px; font-size: 1.2em"
|
:targetIsMe="targetIsMe"
|
||||||
>
|
:year="year"
|
||||||
<div class="col-5 align-self-center text-end">
|
:month="month"
|
||||||
{{ officer.officerLevelText }} :
|
:turn="officer.turn"
|
||||||
</div>
|
:turnTerm="turnTerm"
|
||||||
<div
|
:commandList="unwrap(commandList)"
|
||||||
class="col-7 align-self-center"
|
:turnTime="officer.turnTime"
|
||||||
:style="{
|
:maxTurn="maxChiefTurn"
|
||||||
color: getNpcColor(officer.npcType ?? 0),
|
:maxPushTurn="Math.floor(maxChiefTurn / 2)"
|
||||||
}"
|
:date="date"
|
||||||
>
|
:officer="officer"
|
||||||
{{ officer.name }}
|
@raiseReload="reloadTable()"
|
||||||
</div>
|
/>
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
:class="[
|
|
||||||
'row',
|
|
||||||
'controlPad',
|
|
||||||
chiefLevel == officerLevel ? 'targetIsMe' : 'targetIsNotMe',
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<div class="col-3 col-md-12 order-md-last">
|
|
||||||
<div class="d-grid mb-1 py-1 only500px bg1 center">
|
|
||||||
<div
|
|
||||||
:style="{
|
|
||||||
color: getNpcColor(officer.npcType ?? 0),
|
|
||||||
fontSize: '1.2em',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
{{ officer.name }}
|
|
||||||
</div>
|
|
||||||
<div>{{ officer.officerLevelText }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="row gx-1 gy-1 py-1">
|
|
||||||
<div class="col-md-4 mx-0 mb-0 mt-1 d-grid">
|
|
||||||
<div
|
|
||||||
class="alert alert-primary mb-0 center"
|
|
||||||
style="padding: 0.5rem 0"
|
|
||||||
>
|
|
||||||
{{ serverNow }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<b-dropdown class="col-md-4" left text="턴 선택">
|
|
||||||
<b-dropdown-item @click="selectNone()"
|
|
||||||
>해제</b-dropdown-item
|
|
||||||
>
|
|
||||||
<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>
|
|
||||||
<b-dropdown class="col-md-4" text="반복">
|
|
||||||
<b-dropdown-item
|
|
||||||
v-for="turnIdx in maxPushTurn"
|
|
||||||
:key="turnIdx"
|
|
||||||
@click="repeatNationCommand(turnIdx)"
|
|
||||||
>{{ turnIdx }}턴
|
|
||||||
</b-dropdown-item>
|
|
||||||
</b-dropdown>
|
|
||||||
<b-dropdown
|
|
||||||
class="col-md-6"
|
|
||||||
split
|
|
||||||
text="당기기"
|
|
||||||
@click="pullNationCommandSingle"
|
|
||||||
>
|
|
||||||
<b-dropdown-item
|
|
||||||
v-for="turnIdx in maxPushTurn"
|
|
||||||
:key="turnIdx"
|
|
||||||
@click="pushNationCommand(-turnIdx)"
|
|
||||||
>{{ turnIdx }}턴
|
|
||||||
</b-dropdown-item>
|
|
||||||
</b-dropdown>
|
|
||||||
<b-dropdown
|
|
||||||
class="col-md-6"
|
|
||||||
split
|
|
||||||
text="미루기"
|
|
||||||
@click="pushNationCommandSingle"
|
|
||||||
>
|
|
||||||
<b-dropdown-item
|
|
||||||
v-for="turnIdx in maxPushTurn"
|
|
||||||
:key="turnIdx"
|
|
||||||
@click="pushNationCommand(turnIdx)"
|
|
||||||
>{{ turnIdx }}턴
|
|
||||||
</b-dropdown-item>
|
|
||||||
</b-dropdown>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<ChiefReservedCommand
|
|
||||||
:key="idx"
|
|
||||||
:year="year"
|
|
||||||
:month="month"
|
|
||||||
:turn="officer.turn"
|
|
||||||
:turnTerm="turnTerm"
|
|
||||||
:commandList="commandList"
|
|
||||||
:turnTime="officer.turnTime"
|
|
||||||
:maxTurn="maxChiefTurn"
|
|
||||||
:maxPushTurn="Math.floor(maxChiefTurn / 2)"
|
|
||||||
:date="date"
|
|
||||||
v-model:selectedTurn="turnList"
|
|
||||||
@raiseReload="reloadTable()"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-if="vidx % 4 == 3" :class="['turnIdx', vidx == 7 && !targetIsMe ? undefined : 'only1000px']">
|
||||||
v-if="vidx % 4 == 3"
|
|
||||||
:class="[
|
|
||||||
'turnIdx',
|
|
||||||
vidx == 7 && !targetIsMe ? undefined : 'only1000px',
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<div :class="['subRows', 'bg0']" :style="mainTableGridRows">
|
<div :class="['subRows', 'bg0']" :style="mainTableGridRows">
|
||||||
<div class="bg1"> </div>
|
<div class="bg1"> </div>
|
||||||
<div
|
<div v-for="idx in maxChiefTurn" :key="idx" :class="[`turnIdxRight`, 'align-self-center', 'center']">
|
||||||
v-for="idx in maxChiefTurn"
|
|
||||||
:class="[`turnIdxRight`, 'align-self-center', 'center']"
|
|
||||||
:key="idx"
|
|
||||||
>
|
|
||||||
{{ idx }}
|
{{ idx }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -194,19 +52,12 @@
|
|||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="bottomChiefBox" v-if="chiefList">
|
<div v-if="chiefList" id="bottomChiefBox">
|
||||||
<div id="bottomChiefList" class="c-bg2">
|
<div id="bottomChiefList" class="c-bg2">
|
||||||
<template
|
<template v-for="(chiefLevel, vidx) in [12, 10, 8, 6, 11, 9, 7, 5]" :key="chiefLevel">
|
||||||
v-for="(chiefLevel, vidx) in [12, 10, 8, 6, 11, 9, 7, 5]"
|
<div v-if="vidx % 4 == 0" class="turnIdx subRows bg0" :style="subTableGridRows">
|
||||||
:key="chiefLevel"
|
<div class="bg1" style="grid-row: 1/3" />
|
||||||
>
|
<div v-for="idx in maxChiefTurn" :key="idx" :class="[`turnIdxLeft`]">
|
||||||
<div
|
|
||||||
class="turnIdx subRows bg0"
|
|
||||||
:style="subTableGridRows"
|
|
||||||
v-if="vidx % 4 == 0"
|
|
||||||
>
|
|
||||||
<div class="bg1" style="grid-row: 1/3"></div>
|
|
||||||
<div v-for="idx in maxChiefTurn" :class="[`turnIdxLeft`]" :key="idx">
|
|
||||||
{{ idx }}
|
{{ idx }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -217,13 +68,9 @@
|
|||||||
:isMe="chiefLevel == officerLevel"
|
:isMe="chiefLevel == officerLevel"
|
||||||
@click="viewTarget = chiefLevel"
|
@click="viewTarget = chiefLevel"
|
||||||
/>
|
/>
|
||||||
<div
|
<div v-if="vidx % 4 == 3" class="turnIdx subRows bg0" :style="subTableGridRows">
|
||||||
class="turnIdx subRows bg0"
|
<div class="bg1" style="grid-row: 1/3" />
|
||||||
:style="subTableGridRows"
|
<div v-for="idx in maxChiefTurn" :key="idx" :class="`turnIdxRight`">
|
||||||
v-if="vidx % 4 == 3"
|
|
||||||
>
|
|
||||||
<div class="bg1" style="grid-row: 1/3"></div>
|
|
||||||
<div v-for="idx in maxChiefTurn" :class="`turnIdxRight`" :key="idx">
|
|
||||||
{{ idx }}
|
{{ idx }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -235,255 +82,128 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
declare const staticValues: {
|
||||||
|
serverNick: string;
|
||||||
|
mapName: string;
|
||||||
|
unitSet: string;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script lang="ts" setup>
|
||||||
import "@scss/common/bootstrap5.scss";
|
import "@scss/common/bootstrap5.scss";
|
||||||
import "@scss/game_bg.scss";
|
import "@scss/game_bg.scss";
|
||||||
import "../../css/config.css";
|
import "../../css/config.css";
|
||||||
|
|
||||||
import { computed, defineComponent, reactive, ref, toRefs, watch } from "vue";
|
import { computed, provide, reactive, ref, toRefs, watch } from "vue";
|
||||||
import ChiefReservedCommand from "@/components/ChiefReservedCommand.vue";
|
import ChiefReservedCommand from "@/components/ChiefReservedCommand.vue";
|
||||||
import TopBackBar from "@/components/TopBackBar.vue";
|
import TopBackBar from "@/components/TopBackBar.vue";
|
||||||
import BottomBar from "@/components/BottomBar.vue";
|
import BottomBar from "@/components/BottomBar.vue";
|
||||||
import VueTypes from "vue-types";
|
import VueTypes from "vue-types";
|
||||||
import { isString, range } from "lodash";
|
import { isString } from "lodash";
|
||||||
import { mb_strwidth } from "./util/mb_strwidth";
|
|
||||||
import { entriesWithType } from "./util/entriesWithType";
|
import { entriesWithType } from "./util/entriesWithType";
|
||||||
import { addMilliseconds } from "date-fns";
|
|
||||||
import { formatTime } from "./util/formatTime";
|
|
||||||
import { parseTime } from "./util/parseTime";
|
|
||||||
import { getNpcColor } from "./common_legacy";
|
|
||||||
import TopItem from "@/ChiefCenter/TopItem.vue";
|
import TopItem from "@/ChiefCenter/TopItem.vue";
|
||||||
import BottomItem from "@/ChiefCenter/BottomItem.vue";
|
import BottomItem from "@/ChiefCenter/BottomItem.vue";
|
||||||
import { ChiefResponse, OptionalFull } from "./defs";
|
import type { OptionalFull } from "./defs";
|
||||||
import { SammoAPI } from "./SammoAPI";
|
import { SammoAPI } from "./SammoAPI";
|
||||||
|
import { unwrap } from "@/util/unwrap";
|
||||||
|
import { StoredActionsHelper } from "./util/StoredActionsHelper";
|
||||||
|
import type { ChiefResponse } from "./defs/API/NationCommand";
|
||||||
|
|
||||||
function isDropdownChildren(e?: Event): boolean {
|
const props = defineProps({
|
||||||
if (!e) {
|
maxChiefTurn: VueTypes.number.isRequired,
|
||||||
return false;
|
});
|
||||||
|
|
||||||
|
const tableObj = reactive<Omit<OptionalFull<ChiefResponse>, "result">>({
|
||||||
|
lastExecute: undefined,
|
||||||
|
year: undefined,
|
||||||
|
month: undefined,
|
||||||
|
turnTerm: undefined,
|
||||||
|
date: undefined,
|
||||||
|
chiefList: undefined,
|
||||||
|
isChief: undefined,
|
||||||
|
autorun_limit: undefined,
|
||||||
|
officerLevel: undefined,
|
||||||
|
commandList: undefined,
|
||||||
|
mapName: undefined,
|
||||||
|
unitSet: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { year, month, turnTerm, date, chiefList, officerLevel, commandList } = toRefs(tableObj);
|
||||||
|
|
||||||
|
const viewTarget = ref<number | undefined>();
|
||||||
|
|
||||||
|
const targetIsMe = ref<boolean>(false);
|
||||||
|
watch(viewTarget, (val) => {
|
||||||
|
console.log("targetChange!", val, targetIsMe);
|
||||||
|
if (val === undefined) {
|
||||||
|
targetIsMe.value = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (!e.target) {
|
if (tableObj.officerLevel === undefined) {
|
||||||
return false;
|
targetIsMe.value = false;
|
||||||
}
|
}
|
||||||
if (
|
targetIsMe.value = val === tableObj.officerLevel;
|
||||||
(e.target as HTMLElement).classList.contains("dropdown-item") ||
|
});
|
||||||
(e.target as HTMLElement).classList.contains("dropdown-toggle-split") ||
|
|
||||||
(e.target as HTMLElement).classList.contains("ignoreMe")
|
async function reloadTable(): Promise<void> {
|
||||||
) {
|
try {
|
||||||
return true;
|
const response = await SammoAPI.NationCommand.GetReservedCommand();
|
||||||
|
console.log(response);
|
||||||
|
for (const [key, value] of entriesWithType(response)) {
|
||||||
|
if (key === "result") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key === "officerLevel") {
|
||||||
|
if (value < 5) {
|
||||||
|
tableObj.officerLevel = undefined;
|
||||||
|
} else {
|
||||||
|
tableObj.officerLevel = value as number;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//HACK:
|
||||||
|
tableObj[key as unknown as "year"] = value as unknown as undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewTarget.value === undefined) {
|
||||||
|
if (!tableObj.officerLevel) {
|
||||||
|
viewTarget.value = 12;
|
||||||
|
} else {
|
||||||
|
viewTarget.value = tableObj.officerLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (isString(e)) {
|
||||||
|
alert(e);
|
||||||
|
}
|
||||||
|
console.error(e);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default defineComponent({
|
const mainTableGridRows = computed(() => {
|
||||||
components: {
|
return {
|
||||||
TopBackBar,
|
gridTemplateRows: `24px repeat(${props.maxChiefTurn}, 30px)`,
|
||||||
BottomBar,
|
};
|
||||||
ChiefReservedCommand,
|
|
||||||
TopItem,
|
|
||||||
BottomItem,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
maxChiefTurn: VueTypes.number.isRequired,
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
year() {
|
|
||||||
console.log(this.lastExecute);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
toggleTurn(turnIdx: number) {
|
|
||||||
if (this.turnList.has(turnIdx)) {
|
|
||||||
this.turnList.delete(turnIdx);
|
|
||||||
} else {
|
|
||||||
this.turnList.add(turnIdx);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selectTurn(turnIdx: number) {
|
|
||||||
this.turnList.clear();
|
|
||||||
this.turnList.add(turnIdx);
|
|
||||||
},
|
|
||||||
selectNone() {
|
|
||||||
this.turnList.clear();
|
|
||||||
},
|
|
||||||
selectAll(e: Event | true) {
|
|
||||||
//NOTE: split 구현에 버그가 있어서, 수동으로 구분해야함
|
|
||||||
if (e !== true && isDropdownChildren(e)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.turnList.size * 3 > this.maxChiefTurn) {
|
|
||||||
this.turnList.clear();
|
|
||||||
} else {
|
|
||||||
for (let i = 0; i < this.maxChiefTurn; i++) {
|
|
||||||
this.turnList.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selectStep(begin: number, step: number) {
|
|
||||||
this.turnList.clear();
|
|
||||||
for (const idx of range(0, this.maxChiefTurn)) {
|
|
||||||
if ((idx - begin) % step == 0) {
|
|
||||||
this.turnList.add(idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async repeatNationCommand(amount: number) {
|
|
||||||
try {
|
|
||||||
await SammoAPI.NationCommand.RepeatCommand({ amount });
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
alert(`실패했습니다: ${e}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await this.reloadTable();
|
|
||||||
},
|
|
||||||
async pushNationCommand(amount: number) {
|
|
||||||
try {
|
|
||||||
await SammoAPI.NationCommand.PushCommand({ amount });
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
alert(`실패했습니다: ${e}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await this.reloadTable();
|
|
||||||
},
|
|
||||||
pushNationCommandSingle(e: Event) {
|
|
||||||
//NOTE: split 구현에 버그가 있어서, 수동으로 구분해야함
|
|
||||||
if (isDropdownChildren(e)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void this.pushNationCommand(1);
|
|
||||||
},
|
|
||||||
pullNationCommandSingle(e: Event) {
|
|
||||||
//NOTE: split 구현에 버그가 있어서, 수동으로 구분해야함
|
|
||||||
if (isDropdownChildren(e)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void this.pushNationCommand(-1);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup(props) {
|
|
||||||
const viewTarget = ref<number | undefined>();
|
|
||||||
|
|
||||||
const turnList = ref(new Set<number>());
|
|
||||||
|
|
||||||
const targetIsMe = ref<boolean>(false);
|
|
||||||
watch(viewTarget, (val) => {
|
|
||||||
console.log("targetChange!", val, targetIsMe);
|
|
||||||
if (val === undefined) {
|
|
||||||
targetIsMe.value = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (tableObj.officerLevel === undefined) {
|
|
||||||
targetIsMe.value = false;
|
|
||||||
}
|
|
||||||
targetIsMe.value = val === tableObj.officerLevel;
|
|
||||||
console.log("result", targetIsMe.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
const tableObj = reactive<Omit<OptionalFull<ChiefResponse>, "result">>({
|
|
||||||
lastExecute: undefined,
|
|
||||||
year: undefined,
|
|
||||||
month: undefined,
|
|
||||||
turnTerm: undefined,
|
|
||||||
date: undefined,
|
|
||||||
chiefList: undefined,
|
|
||||||
isChief: undefined,
|
|
||||||
autorun_limit: undefined,
|
|
||||||
officerLevel: undefined,
|
|
||||||
commandList: undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
async function reloadTable(): Promise<void> {
|
|
||||||
try {
|
|
||||||
const response =
|
|
||||||
await SammoAPI.NationCommand.GetReservedCommand<ChiefResponse>();
|
|
||||||
console.log(response);
|
|
||||||
for (const [key, value] of entriesWithType(response)) {
|
|
||||||
if (key === "result") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key === "officerLevel") {
|
|
||||||
if (value < 5) {
|
|
||||||
tableObj.officerLevel = undefined;
|
|
||||||
} else {
|
|
||||||
tableObj.officerLevel = value as number;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//HACK:
|
|
||||||
tableObj[key as unknown as "year"] = value as unknown as undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
const serverNowObj = parseTime(response.date);
|
|
||||||
const clientNowObj = new Date();
|
|
||||||
timeDiff.value = serverNowObj.getTime() - clientNowObj.getTime();
|
|
||||||
|
|
||||||
if (viewTarget.value === undefined) {
|
|
||||||
if (!tableObj.officerLevel) {
|
|
||||||
viewTarget.value = 12;
|
|
||||||
} else {
|
|
||||||
viewTarget.value = tableObj.officerLevel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
if (isString(e)) {
|
|
||||||
alert(e);
|
|
||||||
}
|
|
||||||
console.error(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
|
|
||||||
const mainTableGridRows = computed(() => {
|
|
||||||
return {
|
|
||||||
gridTemplateRows: `24px repeat(${props.maxChiefTurn}, 30px)`,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const subTableGridRows = computed(() => {
|
|
||||||
return {
|
|
||||||
gridTemplateRows: `36px repeat(${props.maxChiefTurn + 1}, 1fr)`,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
void reloadTable();
|
|
||||||
|
|
||||||
const serverNow = ref(formatTime(new Date(), "HH:mm:ss"));
|
|
||||||
const timeDiff = ref(0);
|
|
||||||
|
|
||||||
function updateNow() {
|
|
||||||
const serverNowObj = addMilliseconds(new Date(), timeDiff.value);
|
|
||||||
serverNow.value = formatTime(serverNowObj, "HH:mm:ss");
|
|
||||||
setTimeout(() => {
|
|
||||||
updateNow();
|
|
||||||
}, 1000 - serverNowObj.getMilliseconds());
|
|
||||||
}
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
updateNow();
|
|
||||||
}, 500);
|
|
||||||
|
|
||||||
return {
|
|
||||||
updateNow,
|
|
||||||
serverNow,
|
|
||||||
timeDiff,
|
|
||||||
turnList,
|
|
||||||
...toRefs(tableObj),
|
|
||||||
mb_strwidth,
|
|
||||||
mainTableGridRows,
|
|
||||||
subTableGridRows,
|
|
||||||
reloadTable,
|
|
||||||
getNpcColor,
|
|
||||||
viewTarget,
|
|
||||||
targetIsMe,
|
|
||||||
maxPushTurn: props.maxChiefTurn / 2,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const subTableGridRows = computed(() => {
|
||||||
|
return {
|
||||||
|
gridTemplateRows: `36px repeat(${props.maxChiefTurn + 1}, 1fr)`,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
void reloadTable();
|
||||||
|
|
||||||
|
const storedActionsHelper = new StoredActionsHelper(
|
||||||
|
staticValues.serverNick,
|
||||||
|
"nation",
|
||||||
|
staticValues.mapName,
|
||||||
|
staticValues.unitSet
|
||||||
|
);
|
||||||
|
provide("storedNationActionsHelper", storedActionsHelper);
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "@scss/chiefCenter.scss";
|
@import "@scss/chiefCenter.scss";
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
+57
-143
@@ -1,40 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<top-back-bar :title="title" />
|
<TopBackBar :title="title" />
|
||||||
<div
|
<div
|
||||||
id="container"
|
id="container"
|
||||||
class="bg0 px-2"
|
class="bg0 px-2"
|
||||||
style="
|
style="max-width: 1000px; margin: auto; border: solid 1px #888888; overflow: hidden"
|
||||||
max-width: 1000px;
|
|
||||||
margin: auto;
|
|
||||||
border: solid 1px #888888;
|
|
||||||
overflow: hidden;
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<div id="inheritance_list" class="row">
|
<div id="inheritance_list" class="row">
|
||||||
<template v-for="(text, key) in inheritanceViewText" :key="key">
|
<template v-for="(text, key) in inheritanceViewText" :key="key">
|
||||||
<div
|
<div :id="`inherit_${key}`" class="col col-sm-4 col-12 inherit_item inherit_template_item">
|
||||||
:id="`inherit_${key}`"
|
|
||||||
class="col col-sm-4 col-12 inherit_item inherit_template_item"
|
|
||||||
>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label
|
<label :id="`inherit_${key}_head`" class="inherit_head col col-md-6 col-sm-7 col-6 col-form-label">{{
|
||||||
:id="`inherit_${key}_head`"
|
text.title
|
||||||
class="inherit_head col col-md-6 col-sm-7 col-6 col-form-label"
|
}}</label>
|
||||||
>{{ text.title }}</label
|
|
||||||
>
|
|
||||||
<div class="col col-md-6 col-sm-5 col-6">
|
<div class="col col-md-6 col-sm-5 col-6">
|
||||||
<input
|
<input
|
||||||
|
:id="`inherit_${key}_value`"
|
||||||
type="text"
|
type="text"
|
||||||
class="form-control inherit_value f_tnum"
|
class="form-control inherit_value f_tnum"
|
||||||
readonly
|
readonly
|
||||||
:id="`inherit_${key}_value`"
|
|
||||||
:value="Math.floor(items[key]).toLocaleString()"
|
:value="Math.floor(items[key]).toLocaleString()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="text-align: right">
|
<div style="text-align: right">
|
||||||
<small class="form-text text-muted" v-html="text.info"></small>
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
|
<small class="form-text text-muted" v-html="text.info" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="key == 'new'" style="width: 100%; padding: 0 10px">
|
<div v-if="key == 'new'" style="width: 100%; padding: 0 10px">
|
||||||
@@ -44,22 +35,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="inheritance_store">
|
<div id="inheritance_store">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col"><div class="bg1 a-center">유산 포인트 상점</div></div>
|
<div class="col">
|
||||||
|
<div class="bg1 a-center">유산 포인트 상점</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col offset-md-4 col-md-4 col-sm-6 col-12 py-2">
|
<div class="col offset-md-4 col-md-4 col-sm-6 col-12 py-2">
|
||||||
<div class="row px-4">
|
<div class="row px-4">
|
||||||
<div class="a-right col-6 align-self-center">
|
<div class="a-right col-6 align-self-center">다음 전투 특기 선택</div>
|
||||||
다음 전투 특기 선택
|
|
||||||
</div>
|
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<select class="form-select col-6" v-model="nextSpecialWar">
|
<select v-model="nextSpecialWar" class="form-select col-6">
|
||||||
<option
|
<option v-for="(info, key) in availableSpecialWar" :key="key" :value="key">
|
||||||
v-for="(info, key) in availableSpecialWar"
|
|
||||||
:key="key"
|
|
||||||
:value="key"
|
|
||||||
>
|
|
||||||
{{ info.title }}
|
{{ info.title }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
@@ -67,34 +54,23 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="a-right">
|
<div class="a-right">
|
||||||
<small class="form-text text-muted"
|
<small class="form-text text-muted"
|
||||||
><span
|
><!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
style="color: white"
|
<span style="color: white" v-html="availableSpecialWar[nextSpecialWar].info" /><br />다음에 얻을 전투
|
||||||
v-html="availableSpecialWar[nextSpecialWar].info"
|
특기를 정합니다.<br /><span style="color: white"
|
||||||
/><br />다음에 얻을 전투 특기를 정합니다.<br /><span
|
|
||||||
style="color: white"
|
|
||||||
>필요 포인트: {{ inheritActionCost.nextSpecial }}</span
|
>필요 포인트: {{ inheritActionCost.nextSpecial }}</span
|
||||||
></small
|
></small
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="row px-4">
|
<div class="row px-4">
|
||||||
<b-button
|
<b-button class="col-6 offset-6" variant="primary" @click="setNextSpecialWar"> 구입 </b-button>
|
||||||
class="col-6 offset-6"
|
|
||||||
variant="primary"
|
|
||||||
@click="setNextSpecialWar"
|
|
||||||
>구입</b-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-md-4 col-sm-6 col-12 py-2">
|
<div class="col col-md-4 col-sm-6 col-12 py-2">
|
||||||
<div class="row px-4">
|
<div class="row px-4">
|
||||||
<div class="a-right col-6 align-self-center">유니크 입찰</div>
|
<div class="a-right col-6 align-self-center">유니크 입찰</div>
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<select class="form-select col-6" v-model="specificUnique">
|
<select v-model="specificUnique" class="form-select col-6">
|
||||||
<option
|
<option v-for="(info, key) in availableUnique" :key="key" :value="key">
|
||||||
v-for="(info, key) in availableUnique"
|
|
||||||
:key="key"
|
|
||||||
:value="key"
|
|
||||||
>
|
|
||||||
{{ info.title }}
|
{{ info.title }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
@@ -103,29 +79,23 @@
|
|||||||
<div class="row px-4">
|
<div class="row px-4">
|
||||||
<div class="col f_tnum">
|
<div class="col f_tnum">
|
||||||
<NumberInputWithInfo
|
<NumberInputWithInfo
|
||||||
|
v-model="specificUniqueAmount"
|
||||||
title="입찰 포인트"
|
title="입찰 포인트"
|
||||||
:min="inheritActionCost.minSpecificUnique"
|
:min="inheritActionCost.minSpecificUnique"
|
||||||
:max="items.previous"
|
:max="items.previous"
|
||||||
v-model="specificUniqueAmount"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="a-right">
|
<div class="a-right">
|
||||||
<small class="form-text text-muted"
|
<small class="form-text text-muted"
|
||||||
>얻고자 하는 유니크 아이템을 포인트를 걸어 입찰합니다. 최고
|
>얻고자 하는 유니크 아이템을 포인트를 걸어 입찰합니다. 최고 포인트인 경우 다음 턴에 유니크를 얻습니다.<br />
|
||||||
포인트인 경우 다음 턴에 유니크를 얻습니다.<br /><span
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
style="color: white"
|
<span style="color: white" v-html="availableUnique[specificUnique].info" />
|
||||||
v-html="availableUnique[specificUnique].info"
|
</small>
|
||||||
/></small>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row px-4">
|
<div class="row px-4">
|
||||||
<b-button
|
<b-button class="col-6 offset-6" variant="primary" @click="buySpecificUnique"> 구입 </b-button>
|
||||||
class="col-6 offset-6"
|
|
||||||
variant="primary"
|
|
||||||
@click="buySpecificUnique"
|
|
||||||
>구입</b-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -136,16 +106,11 @@
|
|||||||
<div class="col col-md-4 col-sm-6 col-12 py-2">
|
<div class="col col-md-4 col-sm-6 col-12 py-2">
|
||||||
<div class="row px-4">
|
<div class="row px-4">
|
||||||
<div class="a-right col-6 align-self-center">랜덤 턴 초기화</div>
|
<div class="a-right col-6 align-self-center">랜덤 턴 초기화</div>
|
||||||
<b-button
|
<b-button class="col-6" variant="primary" @click="buySimple('ResetTurnTime')"> 구입 </b-button>
|
||||||
class="col-6"
|
|
||||||
variant="primary"
|
|
||||||
@click="buySimple('ResetTurnTime')"
|
|
||||||
>구입</b-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="a-right">
|
<div class="a-right">
|
||||||
<small class="form-text text-muted"
|
<small class="form-text text-muted"
|
||||||
>다음 턴이 랜덤으로 바뀝니다.<br /><span style="color: white"
|
>다음 턴이 랜덤으로 바뀝니다. (필요 포인트가 피보나치식으로 증가합니다)<br /><span style="color: white"
|
||||||
>필요 포인트: {{ inheritActionCost.resetTurnTime }}</span
|
>필요 포인트: {{ inheritActionCost.resetTurnTime }}</span
|
||||||
></small
|
></small
|
||||||
>
|
>
|
||||||
@@ -154,12 +119,7 @@
|
|||||||
<div class="col col-md-4 col-sm-6 col-12 py-2">
|
<div class="col col-md-4 col-sm-6 col-12 py-2">
|
||||||
<div class="row px-4">
|
<div class="row px-4">
|
||||||
<div class="a-right col-6 align-self-center">랜덤 유니크 획득</div>
|
<div class="a-right col-6 align-self-center">랜덤 유니크 획득</div>
|
||||||
<b-button
|
<b-button class="col-6" variant="primary" @click="buySimple('BuyRandomUnique')"> 구입 </b-button>
|
||||||
class="col-6"
|
|
||||||
variant="primary"
|
|
||||||
@click="buySimple('BuyRandomUnique')"
|
|
||||||
>구입</b-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="a-right">
|
<div class="a-right">
|
||||||
<small class="form-text text-muted"
|
<small class="form-text text-muted"
|
||||||
@@ -171,19 +131,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col col-md-4 col-sm-6 col-12 py-2">
|
<div class="col col-md-4 col-sm-6 col-12 py-2">
|
||||||
<div class="row px-4">
|
<div class="row px-4">
|
||||||
<div class="a-right col-6 align-self-center">
|
<div class="a-right col-6 align-self-center">즉시 전투 특기 초기화</div>
|
||||||
즉시 전투 특기 초기화
|
<b-button class="col-6" variant="primary" @click="buySimple('ResetSpecialWar')"> 구입 </b-button>
|
||||||
</div>
|
|
||||||
<b-button
|
|
||||||
class="col-6"
|
|
||||||
variant="primary"
|
|
||||||
@click="buySimple('ResetSpecialWar')"
|
|
||||||
>구입</b-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="a-right">
|
<div class="a-right">
|
||||||
<small class="form-text text-muted"
|
<small class="form-text text-muted"
|
||||||
>즉시 전투 특기를 초기화합니다.<br /><span style="color: white"
|
>즉시 전투 특기를 초기화합니다. (필요 포인트가 피보나치식으로 증가합니다)<br /><span style="color: white"
|
||||||
>필요 포인트: {{ inheritActionCost.resetSpecialWar }}</span
|
>필요 포인트: {{ inheritActionCost.resetSpecialWar }}</span
|
||||||
></small
|
></small
|
||||||
>
|
>
|
||||||
@@ -195,23 +148,17 @@
|
|||||||
<hr :style="{ opacity: 0.5 }" />
|
<hr :style="{ opacity: 0.5 }" />
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div
|
<div v-for="(info, buffKey) in inheritBuffHelpText" :key="buffKey" class="col col-md-4 col-sm-6 col-12">
|
||||||
class="col col-md-4 col-sm-6 col-12"
|
|
||||||
v-for="(info, buffKey) in inheritBuffHelpText"
|
|
||||||
:key="buffKey"
|
|
||||||
>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label class="col col-sm-6 col-form-label" :for="`buff-${buffKey}`">{{
|
<label class="col col-sm-6 col-form-label" :for="`buff-${buffKey}`">{{ info.title }}</label>
|
||||||
info.title
|
|
||||||
}}</label>
|
|
||||||
<div class="col col-sm-6 f_tnum">
|
<div class="col col-sm-6 f_tnum">
|
||||||
<b-form-input
|
<b-form-input
|
||||||
:id="`buff-${buffKey}`"
|
:id="`buff-${buffKey}`"
|
||||||
type="number"
|
|
||||||
v-model="inheritBuff[buffKey]"
|
v-model="inheritBuff[buffKey]"
|
||||||
|
type="number"
|
||||||
:min="prevInheritBuff[buffKey] ?? 0"
|
:min="prevInheritBuff[buffKey] ?? 0"
|
||||||
:max="maxInheritBuff"
|
:max="maxInheritBuff"
|
||||||
></b-form-input>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align: right">
|
<div style="text-align: right">
|
||||||
@@ -219,8 +166,7 @@
|
|||||||
>{{ info.info }}<br /><span style="color: white"
|
>{{ info.info }}<br /><span style="color: white"
|
||||||
>필요 포인트:
|
>필요 포인트:
|
||||||
{{
|
{{
|
||||||
inheritActionCost.buff[inheritBuff[buffKey]] -
|
inheritActionCost.buff[inheritBuff[buffKey]] - inheritActionCost.buff[prevInheritBuff[buffKey] ?? 0]
|
||||||
inheritActionCost.buff[prevInheritBuff[buffKey] ?? 0]
|
|
||||||
}}</span
|
}}</span
|
||||||
></small
|
></small
|
||||||
>
|
>
|
||||||
@@ -228,15 +174,11 @@
|
|||||||
<div class="row px-4" style="margin-bottom: 1em">
|
<div class="row px-4" style="margin-bottom: 1em">
|
||||||
<b-button
|
<b-button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
@click="inheritBuff[buffKey] = prevInheritBuff[buffKey] ?? 0"
|
|
||||||
class="col col-md-6 col-4 offset-md-0 offset-4"
|
class="col col-md-6 col-4 offset-md-0 offset-4"
|
||||||
>리셋</b-button
|
@click="inheritBuff[buffKey] = prevInheritBuff[buffKey] ?? 0"
|
||||||
><b-button
|
|
||||||
variant="primary"
|
|
||||||
class="col col-md-6 col-4"
|
|
||||||
@click="buyInheritBuff(buffKey)"
|
|
||||||
>구입</b-button
|
|
||||||
>
|
>
|
||||||
|
리셋 </b-button
|
||||||
|
><b-button variant="primary" class="col col-md-6 col-4" @click="buyInheritBuff(buffKey)"> 구입 </b-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -245,7 +187,7 @@
|
|||||||
<div class="bg1 a-center">유산 포인트 변경 내역(최근 30건)</div>
|
<div class="bg1 a-center">유산 포인트 변경 내역(최근 30건)</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" v-for="(log, idx) in lastInheritPointLogs" :key="idx">
|
<div v-for="(log, idx) in lastInheritPointLogs" :key="idx" class="row">
|
||||||
<div class="col a-right" style="max-width: 20ch">
|
<div class="col a-right" style="max-width: 20ch">
|
||||||
<small class="text-muted tnum">[{{ log.date }}]</small>
|
<small class="text-muted tnum">[{{ log.date }}]</small>
|
||||||
</div>
|
</div>
|
||||||
@@ -264,6 +206,7 @@ import TopBackBar from "@/components/TopBackBar.vue";
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import NumberInputWithInfo from "@/components/NumberInputWithInfo.vue";
|
import NumberInputWithInfo from "@/components/NumberInputWithInfo.vue";
|
||||||
import { SammoAPI } from "./SammoAPI";
|
import { SammoAPI } from "./SammoAPI";
|
||||||
|
import type { inheritBuffType } from "./defs/API/InheritAction";
|
||||||
|
|
||||||
type InheritanceType =
|
type InheritanceType =
|
||||||
| "previous"
|
| "previous"
|
||||||
@@ -291,10 +234,7 @@ declare const lastInheritPointLogs: {
|
|||||||
|
|
||||||
declare const items: Record<InheritanceType, number>;
|
declare const items: Record<InheritanceType, number>;
|
||||||
|
|
||||||
const inheritanceViewText: Record<
|
const inheritanceViewText: Record<InheritanceViewType, { title: string; info: string }> = {
|
||||||
InheritanceViewType,
|
|
||||||
{ title: string; info: string }
|
|
||||||
> = {
|
|
||||||
sum: {
|
sum: {
|
||||||
title: "총 포인트",
|
title: "총 포인트",
|
||||||
info: "다음 플레이에서 사용할 수 있는 총 포인트입니다.",
|
info: "다음 플레이에서 사용할 수 있는 총 포인트입니다.",
|
||||||
@@ -353,15 +293,6 @@ const inheritanceViewText: Record<
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
type inheritBuffType =
|
|
||||||
| "warAvoidRatio"
|
|
||||||
| "warCriticalRatio"
|
|
||||||
| "warMagicTrialProb"
|
|
||||||
| "domesticSuccessProb"
|
|
||||||
| "domesticFailProb"
|
|
||||||
| "warAvoidRatioOppose"
|
|
||||||
| "warCriticalRatioOppose"
|
|
||||||
| "warMagicTrialProbOppose";
|
|
||||||
|
|
||||||
declare const currentInheritBuff: {
|
declare const currentInheritBuff: {
|
||||||
[v in inheritBuffType]: number | undefined;
|
[v in inheritBuffType]: number | undefined;
|
||||||
@@ -439,11 +370,13 @@ declare const availableUnique: Record<
|
|||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "PageInheritPoint",
|
name: "PageInheritPoint",
|
||||||
|
components: {
|
||||||
|
TopBackBar,
|
||||||
|
NumberInputWithInfo,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
const inheritBuff = {} as Record<inheritBuffType, number>;
|
const inheritBuff = {} as Record<inheritBuffType, number>;
|
||||||
for (const buffKey of Object.keys(
|
for (const buffKey of Object.keys(inheritBuffHelpText) as inheritBuffType[]) {
|
||||||
inheritBuffHelpText
|
|
||||||
) as inheritBuffType[]) {
|
|
||||||
inheritBuff[buffKey] = currentInheritBuff[buffKey] ?? 0;
|
inheritBuff[buffKey] = currentInheritBuff[buffKey] ?? 0;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@@ -486,9 +419,7 @@ export default defineComponent({
|
|||||||
alert("낮출 수 없습니다.");
|
alert("낮출 수 없습니다.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const cost =
|
const cost = this.inheritActionCost.buff[level] - this.inheritActionCost.buff[prevLevel];
|
||||||
this.inheritActionCost.buff[level] -
|
|
||||||
this.inheritActionCost.buff[prevLevel];
|
|
||||||
if (this.items.previous < cost) {
|
if (this.items.previous < cost) {
|
||||||
alert("유산 포인트가 부족합니다.");
|
alert("유산 포인트가 부족합니다.");
|
||||||
return;
|
return;
|
||||||
@@ -496,11 +427,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
const name = inheritBuffHelpText[buffKey].title;
|
const name = inheritBuffHelpText[buffKey].title;
|
||||||
|
|
||||||
if (
|
if (!confirm(`${name}를 ${level}등급으로 올릴까요? ${cost} 포인트가 소모됩니다.`)) {
|
||||||
!confirm(
|
|
||||||
`${name}를 ${level}등급으로 올릴까요? ${cost} 포인트가 소모됩니다.`
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,9 +446,7 @@ export default defineComponent({
|
|||||||
//TODO: 페이지 새로고침 필요없이 하도록
|
//TODO: 페이지 새로고침 필요없이 하도록
|
||||||
location.reload();
|
location.reload();
|
||||||
},
|
},
|
||||||
async buySimple(
|
async buySimple(type: "ResetTurnTime" | "BuyRandomUnique" | "ResetSpecialWar") {
|
||||||
type: "ResetTurnTime" | "BuyRandomUnique" | "ResetSpecialWar"
|
|
||||||
) {
|
|
||||||
const costMap: Record<typeof type, number> = {
|
const costMap: Record<typeof type, number> = {
|
||||||
ResetTurnTime: inheritActionCost.resetTurnTime,
|
ResetTurnTime: inheritActionCost.resetTurnTime,
|
||||||
ResetSpecialWar: inheritActionCost.resetSpecialWar,
|
ResetSpecialWar: inheritActionCost.resetSpecialWar,
|
||||||
@@ -548,7 +473,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await SammoAPI.InheritAction[type]({});
|
await SammoAPI.InheritAction[type]();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
alert(`실패했습니다: ${e}`);
|
alert(`실패했습니다: ${e}`);
|
||||||
@@ -560,8 +485,7 @@ export default defineComponent({
|
|||||||
location.reload();
|
location.reload();
|
||||||
},
|
},
|
||||||
async setNextSpecialWar() {
|
async setNextSpecialWar() {
|
||||||
const specialWarName =
|
const specialWarName = this.availableSpecialWar[this.nextSpecialWar].title ?? undefined;
|
||||||
this.availableSpecialWar[this.nextSpecialWar].title ?? undefined;
|
|
||||||
if (specialWarName === undefined) {
|
if (specialWarName === undefined) {
|
||||||
alert(`잘못된 타입: ${this.nextSpecialWar}`);
|
alert(`잘못된 타입: ${this.nextSpecialWar}`);
|
||||||
return;
|
return;
|
||||||
@@ -573,11 +497,7 @@ export default defineComponent({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//TODO: JosaUtil
|
//TODO: JosaUtil
|
||||||
if (
|
if (!confirm(`${cost} 포인트로 다음 전특을 ${specialWarName}(으)로 고정하겠습니까?`)) {
|
||||||
!confirm(
|
|
||||||
`${cost} 포인트로 다음 전특을 ${specialWarName}(으)로 고정하겠습니까?`
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,8 +516,7 @@ export default defineComponent({
|
|||||||
location.reload();
|
location.reload();
|
||||||
},
|
},
|
||||||
async buySpecificUnique() {
|
async buySpecificUnique() {
|
||||||
const uniqueName =
|
const uniqueName = this.availableUnique[this.specificUnique].title ?? undefined;
|
||||||
this.availableUnique[this.specificUnique].title ?? undefined;
|
|
||||||
if (uniqueName === undefined) {
|
if (uniqueName === undefined) {
|
||||||
alert(`잘못된 타입: ${this.specificUnique}`);
|
alert(`잘못된 타입: ${this.specificUnique}`);
|
||||||
return;
|
return;
|
||||||
@@ -629,14 +548,9 @@ export default defineComponent({
|
|||||||
location.reload();
|
location.reload();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
|
||||||
TopBackBar,
|
|
||||||
NumberInputWithInfo,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.col-form-label {
|
.col-form-label {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
@@ -650,4 +564,4 @@ export default defineComponent({
|
|||||||
.tnum {
|
.tnum {
|
||||||
font-feature-settings: "tnum";
|
font-feature-settings: "tnum";
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
+293
-311
@@ -1,27 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<top-back-bar title="장수 생성" />
|
<TopBackBar title="장수 생성" />
|
||||||
|
|
||||||
<div id="container" class="bg0">
|
<div v-if="gameConstStore && args" id="container" class="bg0">
|
||||||
<div class="nation-list">
|
<div class="nation-list">
|
||||||
<div class="nation-header nation-row bg1 center">
|
<div class="nation-header nation-row bg1 center">
|
||||||
<div>국가명</div>
|
<div>국가명</div>
|
||||||
<div>임관권유문</div>
|
<div>임관권유문</div>
|
||||||
<div class="display-toggle d-grid">
|
<div class="display-toggle d-grid">
|
||||||
<b-button
|
<b-button
|
||||||
|
v-model="displayTable"
|
||||||
:pressed="displayTable"
|
:pressed="displayTable"
|
||||||
:variant="displayTable ? 'info' : 'secondary'"
|
:variant="displayTable ? 'info' : 'secondary'"
|
||||||
v-model="displayTable"
|
|
||||||
@click="displayTable = !displayTable"
|
@click="displayTable = !displayTable"
|
||||||
>{{ displayTable ? "숨기기" : "보이기" }}</b-button>
|
>
|
||||||
|
{{ displayTable ? "숨기기" : "보이기" }}
|
||||||
|
</b-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="zoom-toggle d-grid">
|
<div class="zoom-toggle d-grid">
|
||||||
<b-button
|
<b-button
|
||||||
|
v-model="toggleZoom"
|
||||||
:pressed="toggleZoom"
|
:pressed="toggleZoom"
|
||||||
:variant="toggleZoom ? 'info' : 'secondary'"
|
:variant="toggleZoom ? 'info' : 'secondary'"
|
||||||
v-model="toggleZoom"
|
|
||||||
@click="toggleZoom = !toggleZoom"
|
|
||||||
:disabled="!displayTable"
|
:disabled="!displayTable"
|
||||||
>{{ toggleZoom ? "작게 보기" : "크게 보기" }}</b-button>
|
@click="toggleZoom = !toggleZoom"
|
||||||
|
>
|
||||||
|
{{ toggleZoom ? "작게 보기" : "크게 보기" }}
|
||||||
|
</b-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="displayTable">
|
<template v-if="displayTable">
|
||||||
@@ -38,9 +42,12 @@
|
|||||||
}"
|
}"
|
||||||
class="d-grid"
|
class="d-grid"
|
||||||
>
|
>
|
||||||
<div class="align-self-center center">{{ nation.name }}</div>
|
<div class="align-self-center center">
|
||||||
|
{{ nation.name }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="nation-scout-plate align-self-center">
|
<div class="nation-scout-plate align-self-center">
|
||||||
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
<div class="nation-scout-msg" v-html="nation.scoutmsg ?? '-'" />
|
<div class="nation-scout-msg" v-html="nation.scoutmsg ?? '-'" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -60,32 +67,22 @@
|
|||||||
<div class="col col-md-1 col-3 a-right align-self-center">전콘 사용</div>
|
<div class="col col-md-1 col-3 a-right align-self-center">전콘 사용</div>
|
||||||
<div class="col col-md-4 col-9 align-self-center">
|
<div class="col col-md-4 col-9 align-self-center">
|
||||||
<img style="height: 64px; width: 64px" :src="iconPath" />
|
<img style="height: 64px; width: 64px" :src="iconPath" />
|
||||||
<label>
|
<label> <input v-model="args.pic" type="checkbox" /> 사용 </label>
|
||||||
<input type="checkbox" v-model="args.pic" /> 사용
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-md-4 col-3 align-self-center a-right">성격</div>
|
<div class="col col-md-4 col-3 align-self-center a-right">성격</div>
|
||||||
|
|
||||||
<div class="col col-md-8 col-9 align-self-center">
|
<div class="col col-md-8 col-9 align-self-center">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-md-3 col-4 align-self-center">
|
<div class="col col-md-3 col-4 align-self-center">
|
||||||
<select
|
<select v-model="args.character" class="form-select form-inline" style="max-width: 20ch">
|
||||||
class="form-select form-inline"
|
<option v-for="(personalityObj, key) in availablePersonality" :key="key" :value="key">
|
||||||
style="max-width: 20ch"
|
{{ personalityObj.name }}
|
||||||
v-model="args.character"
|
</option>
|
||||||
>
|
|
||||||
<option
|
|
||||||
v-for="(personalityObj, key) in availablePersonality"
|
|
||||||
:key="key"
|
|
||||||
:value="key"
|
|
||||||
>{{ personalityObj.name }}</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-md-9 col-8 align-self-center">
|
<div class="col col-md-9 col-8 align-self-center">
|
||||||
<small class="text-muted">
|
<small class="text-muted">
|
||||||
{{
|
{{ availablePersonality[args.character].info }}
|
||||||
availablePersonality[args.character].info
|
|
||||||
}}
|
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -103,37 +100,35 @@
|
|||||||
<small class="text-muted">통/무/지</small>
|
<small class="text-muted">통/무/지</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-md-2 col-3 align-self-center">
|
<div class="col col-md-2 col-3 align-self-center">
|
||||||
<input type="number" class="form-control" v-model="args.leadership" />
|
<input v-model="args.leadership" type="number" class="form-control" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-md-2 col-3 align-self-center">
|
<div class="col col-md-2 col-3 align-self-center">
|
||||||
<input type="number" class="form-control" v-model="args.strength" />
|
<input v-model="args.strength" type="number" class="form-control" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-md-2 col-3 align-self-center">
|
<div class="col col-md-2 col-3 align-self-center">
|
||||||
<input type="number" class="form-control" v-model="args.intel" />
|
<input v-model="args.intel" type="number" class="form-control" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" style="margin-top: 1em">
|
<div class="row" style="margin-top: 1em">
|
||||||
<div class="col col-md-4 col-3 a-right align-self-center">능력치 조절</div>
|
<div class="col col-md-4 col-3 a-right align-self-center">능력치 조절</div>
|
||||||
<div class="col col-md-8 col-9">
|
<div class="col col-md-8 col-9">
|
||||||
<b-button variant="secondary" class="stat-btn" @click="randStatRandom">랜덤형</b-button>
|
<b-button variant="secondary" class="stat-btn" @click="randStatRandom"> 랜덤형 </b-button>
|
||||||
<b-button variant="secondary" class="stat-btn" @click="randStatLeadPow">통솔무력형</b-button>
|
<b-button variant="secondary" class="stat-btn" @click="randStatLeadPow"> 통솔무력형 </b-button>
|
||||||
<b-button variant="secondary" class="stat-btn" @click="randStatLeadInt">통솔지력형</b-button>
|
<b-button variant="secondary" class="stat-btn" @click="randStatLeadInt"> 통솔지력형 </b-button>
|
||||||
<b-button variant="secondary" class="stat-btn" @click="randStatPowInt">무력지력형</b-button>
|
<b-button variant="secondary" class="stat-btn" @click="randStatPowInt"> 무력지력형 </b-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" style="border-top: solid 1px #aaa; margin-top: 0.5em">
|
<div class="row" style="border-top: solid 1px #aaa; margin-top: 0.5em">
|
||||||
<div class="col a-center" style="color: orange">
|
<div class="col a-center" style="color: orange">
|
||||||
모든 능력치는 ( {{ stats.min }} <= 능력치 <= {{ stats.max }} )
|
모든 능력치는 ( {{ stats.min }} <= 능력치 <= {{ stats.max }} ) 사이로 잡으셔야 합니다. <br />그 외의
|
||||||
사이로 잡으셔야 합니다.
|
능력치는 가입되지 않습니다.
|
||||||
<br />그 외의 능력치는 가입되지 않습니다.
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col a-center">
|
<div class="col a-center">
|
||||||
능력치의 총합은 {{ stats.total }} 입니다. 가입후 {{ stats.bonusMin }} ~
|
능력치의 총합은 {{ stats.total }} 입니다. 가입후 {{ stats.bonusMin }} ~ {{ stats.bonusMax }} 의 능력치 보너스를
|
||||||
{{ stats.bonusMax }} 의 능력치 보너스를 받게 됩니다.
|
받게 됩니다. <br />임의의 도시에서 재야로 시작하며 건국과 임관은 게임 내에서 실행합니다.
|
||||||
<br />임의의 도시에서 재야로 시작하며 건국과 임관은 게임 내에서 실행합니다.
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -141,20 +136,18 @@
|
|||||||
<div class="col col-md-11 col-9 center align-self-center">유산 포인트 사용</div>
|
<div class="col col-md-11 col-9 center align-self-center">유산 포인트 사용</div>
|
||||||
<div class="col col-md-1 col-3">
|
<div class="col col-md-1 col-3">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" v-model="displayInherit" />
|
<input v-model="displayInherit" type="checkbox" />
|
||||||
{{
|
{{ displayInherit ? "숨기기" : "보이기" }}
|
||||||
displayInherit ? "숨기기" : "보이기"
|
|
||||||
}}
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="inherit-block" v-if="displayInherit">
|
<div v-if="displayInherit" class="inherit-block">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo title="보유한 유산 포인트" v-model="inheritTotalPoint" :readonly="true" />
|
<NumberInputWithInfo v-model="inheritTotalPoint" title="보유한 유산 포인트" :readonly="true" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo title="필요 유산 포인트" v-model="inheritRequiredPoint" :readonly="true" />
|
<NumberInputWithInfo v-model="inheritRequiredPoint" title="필요 유산 포인트" :readonly="true" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
@@ -163,28 +156,17 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-6 a-right align-self-center">천재로 생성</div>
|
<div class="col col-6 a-right align-self-center">천재로 생성</div>
|
||||||
<div class="col col-6 align-self-center">
|
<div class="col col-6 align-self-center">
|
||||||
<select
|
<select v-model="args.inheritSpecial" class="form-select form-inline" style="max-width: 20ch">
|
||||||
class="form-select form-inline"
|
|
||||||
style="max-width: 20ch"
|
|
||||||
v-model="args.inheritSpecial"
|
|
||||||
>
|
|
||||||
<option :value="undefined">사용안함</option>
|
<option :value="undefined">사용안함</option>
|
||||||
<option
|
<option v-for="(inheritSpecial, key) in availableInheritSpecial" :key="key" :value="key">
|
||||||
v-for="(inheritSpecial, key) in availableInheritSpecial"
|
{{ inheritSpecial.name }}
|
||||||
:key="key"
|
</option>
|
||||||
:value="key"
|
|
||||||
>{{ inheritSpecial.name }}</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col align-self-center">
|
<div class="col align-self-center">
|
||||||
<small
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
class="text-muted"
|
<small class="text-muted" v-html="availableInheritSpecial[args.inheritSpecial ?? '']?.info" />
|
||||||
v-html="
|
|
||||||
(availableInheritSpecial[args.inheritSpecial ?? ''] ?? { info: '' })
|
|
||||||
.info
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -192,17 +174,11 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col col-6 a-right align-self-center">도시</div>
|
<div class="col col-6 a-right align-self-center">도시</div>
|
||||||
<div class="col col-6 align-self-center">
|
<div class="col col-6 align-self-center">
|
||||||
<select
|
<select v-model="args.inheritCity" class="form-select form-inline" style="max-width: 20ch">
|
||||||
class="form-select form-inline"
|
|
||||||
style="max-width: 20ch"
|
|
||||||
v-model="args.inheritCity"
|
|
||||||
>
|
|
||||||
<option :value="undefined">사용안함</option>
|
<option :value="undefined">사용안함</option>
|
||||||
<option
|
<option v-for="city in availableInheritCity" :key="city.id" :value="city.id">
|
||||||
v-for="city in availableInheritCity"
|
{{ `[${city.region}] ${city.name}` }}
|
||||||
:key="city[0]"
|
</option>
|
||||||
:value="city[0]"
|
|
||||||
>{{ `[${city[1]}] ${city[2]}` }}</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -210,28 +186,25 @@
|
|||||||
|
|
||||||
<div class="col col-md-6 col-sm-6 col-12 p-2 align-self-center">
|
<div class="col col-md-6 col-sm-6 col-12 p-2 align-self-center">
|
||||||
<div class="a-center">
|
<div class="a-center">
|
||||||
<label>
|
<label> <input v-model="inheritTurnTimeSet" type="checkbox" />턴 시간 고정 </label>
|
||||||
<input type="checkbox" v-model="inheritTurnTimeSet" />턴 시간
|
|
||||||
고정
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="row turn_time_pad">
|
<div class="row turn_time_pad">
|
||||||
<div class="col col-md-4 offset-md-3 col-4 offset-3">
|
<div class="col col-md-4 offset-md-3 col-4 offset-3">
|
||||||
<NumberInputWithInfo
|
<NumberInputWithInfo
|
||||||
|
v-model="inheritTurnTimeMinute"
|
||||||
:readonly="!inheritTurnTimeSet"
|
:readonly="!inheritTurnTimeSet"
|
||||||
:min="0"
|
:min="0"
|
||||||
:max="1 - turnterm"
|
:max="1 - turnterm"
|
||||||
v-model="inheritTurnTimeMinute"
|
|
||||||
:right="true"
|
:right="true"
|
||||||
title="분"
|
title="분"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-md-4 col-4">
|
<div class="col col-md-4 col-4">
|
||||||
<NumberInputWithInfo
|
<NumberInputWithInfo
|
||||||
|
v-model="inheritTurnTimeSecond"
|
||||||
:readonly="!inheritTurnTimeSet"
|
:readonly="!inheritTurnTimeSet"
|
||||||
:min="0"
|
:min="0"
|
||||||
:max="60"
|
:max="60"
|
||||||
v-model="inheritTurnTimeSecond"
|
|
||||||
:right="true"
|
:right="true"
|
||||||
title="초"
|
title="초"
|
||||||
/>
|
/>
|
||||||
@@ -243,13 +216,13 @@
|
|||||||
<div class="a-center">추가 능력치 고정</div>
|
<div class="a-center">추가 능력치 고정</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo title="통솔" v-model="(args.inheritBonusStat ?? [0, 0, 0])[0]" />
|
<NumberInputWithInfo v-model="(args.inheritBonusStat ?? [0, 0, 0])[0]" :max="stats.bonusMax" title="통솔" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo title="무력" v-model="(args.inheritBonusStat ?? [0, 0, 0])[1]" />
|
<NumberInputWithInfo v-model="(args.inheritBonusStat ?? [0, 0, 0])[1]" :max="stats.bonusMax" title="무력" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo title="지력" v-model="(args.inheritBonusStat ?? [0, 0, 0])[2]" />
|
<NumberInputWithInfo v-model="(args.inheritBonusStat ?? [0, 0, 0])[2]" :max="stats.bonusMax" title="지력" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -258,262 +231,271 @@
|
|||||||
|
|
||||||
<div class="row" style="border-top: solid 1px #aaa">
|
<div class="row" style="border-top: solid 1px #aaa">
|
||||||
<div class="col a-center" style="margin: 0.5em">
|
<div class="col a-center" style="margin: 0.5em">
|
||||||
<b-button color="primary" @click="submitForm">장수 생성</b-button>
|
<b-button color="primary" @click="submitForm"> 장수 생성 </b-button>
|
||||||
<b-button color="secondary" @click="resetArgs">다시 입력</b-button>
|
<b-button color="secondary" @click="resetArgs"> 다시 입력 </b-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
declare const staticValues: {
|
||||||
|
nationList: {
|
||||||
|
nation: number;
|
||||||
|
name: string;
|
||||||
|
color: string;
|
||||||
|
scout: number;
|
||||||
|
scoutmsg?: string;
|
||||||
|
}[];
|
||||||
|
turnterm: number;
|
||||||
|
|
||||||
|
member: {
|
||||||
|
name: string;
|
||||||
|
grade: number;
|
||||||
|
picture: string;
|
||||||
|
imgsvr: 0 | 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
serverID: string;
|
||||||
|
inheritTotalPoint: number;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script lang="ts" setup>
|
||||||
import "@scss/common/bootstrap5.scss";
|
import "@scss/common/bootstrap5.scss";
|
||||||
import "@scss/game_bg.scss";
|
import "@scss/game_bg.scss";
|
||||||
|
|
||||||
import { defineComponent } from "vue";
|
|
||||||
import TopBackBar from "@/components/TopBackBar.vue";
|
import TopBackBar from "@/components/TopBackBar.vue";
|
||||||
import { getIconPath } from "@util/getIconPath";
|
import { getIconPath } from "@util/getIconPath";
|
||||||
import { isBrightColor } from "@util/isBrightColor";
|
import { isBrightColor } from "@util/isBrightColor";
|
||||||
import {
|
import { abilityLeadint, abilityLeadpow, abilityPowint, abilityRand } from "@util/generalStats";
|
||||||
abilityLeadint,
|
import { shuffle, sum } from "lodash";
|
||||||
abilityLeadpow,
|
|
||||||
abilityPowint,
|
|
||||||
abilityRand,
|
|
||||||
} from "@util/generalStats";
|
|
||||||
import { clone, shuffle, sum } from "lodash";
|
|
||||||
import NumberInputWithInfo from "@/components/NumberInputWithInfo.vue";
|
import NumberInputWithInfo from "@/components/NumberInputWithInfo.vue";
|
||||||
import { SammoAPI } from "./SammoAPI";
|
import { SammoAPI } from "./SammoAPI";
|
||||||
|
import type { JoinArgs } from "./defs/API/General";
|
||||||
|
import { GameConstStore, getGameConstStore } from "@/GameConstStore";
|
||||||
|
import { computed, onMounted, ref, watch } from "vue";
|
||||||
|
import type { CityID, GameIActionInfo } from "./defs/GameObj";
|
||||||
|
import { unwrap } from "@/util/unwrap";
|
||||||
|
|
||||||
declare const nationList: {
|
const gameConstStore = ref<GameConstStore>();
|
||||||
nation: number;
|
|
||||||
name: string;
|
|
||||||
color: string;
|
|
||||||
scout: number;
|
|
||||||
scoutmsg?: string;
|
|
||||||
}[];
|
|
||||||
declare const availablePersonality: {
|
|
||||||
[key: string]: {
|
|
||||||
name: string;
|
|
||||||
info: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
declare const availableInheritSpecial: {
|
const { serverID, member, turnterm } = staticValues;
|
||||||
[key: string]: {
|
|
||||||
name: string;
|
|
||||||
info: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
declare const availableInheritCity: [number, string, string][];
|
const nationList = ref(shuffle(staticValues.nationList));
|
||||||
|
const args = ref<JoinArgs>();
|
||||||
|
|
||||||
declare const turnterm: number;
|
const stats = ref({
|
||||||
|
min: 50,
|
||||||
|
max: 50,
|
||||||
|
total: 50,
|
||||||
|
bonusMin: 1,
|
||||||
|
bonusMax: 5,
|
||||||
|
});
|
||||||
|
|
||||||
declare const member: {
|
const inheritTotalPoint = ref(staticValues.inheritTotalPoint);
|
||||||
name: string;
|
const availableInheritCity = ref<{ id: CityID; name: string; region: string }[]>([]);
|
||||||
grade: number;
|
const availableInheritSpecial = ref<Record<string, GameIActionInfo>>({});
|
||||||
picture: string;
|
const availablePersonality = ref<Record<string, GameIActionInfo>>({});
|
||||||
imgsvr: 0 | 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
declare const stats: {
|
watch(gameConstStore, (gameConst) => {
|
||||||
min: number;
|
if (gameConst === undefined) {
|
||||||
max: number;
|
console.error();
|
||||||
total: number;
|
return;
|
||||||
bonusMin: number;
|
|
||||||
bonusMax: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
declare const inheritPoints: {
|
|
||||||
special: number;
|
|
||||||
turnTime: number;
|
|
||||||
city: number;
|
|
||||||
stat: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
declare const serverID: string;
|
|
||||||
declare const inheritTotalPoint: number;
|
|
||||||
|
|
||||||
declare module "@vue/runtime-core" {
|
|
||||||
interface ComponentCustomProperties {
|
|
||||||
member: typeof member;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
availableInheritCity.value = (() => {
|
||||||
|
const cityList: { id: CityID; name: string; region: string }[] = [];
|
||||||
|
for (const city of Object.values(gameConst.cityConst)) {
|
||||||
|
cityList.push({
|
||||||
|
id: city.id,
|
||||||
|
name: city.name,
|
||||||
|
region: gameConst.cityConstMap.region[city.region] as string,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
cityList.sort((lhs, rhs) => {
|
||||||
|
const rC = lhs.region.localeCompare(rhs.region);
|
||||||
|
if (rC != 0) return rC;
|
||||||
|
return lhs.name.localeCompare(rhs.name);
|
||||||
|
});
|
||||||
|
return cityList;
|
||||||
|
})();
|
||||||
|
|
||||||
|
availableInheritSpecial.value = (() => {
|
||||||
|
const specialList: typeof availableInheritSpecial.value = {};
|
||||||
|
for (const specialWarID of Object.values(gameConst.gameConst.availableSpecialWar)) {
|
||||||
|
specialList[specialWarID] = unwrap(gameConst.iActionInfo.specialWar[specialWarID]);
|
||||||
|
}
|
||||||
|
return specialList;
|
||||||
|
})();
|
||||||
|
|
||||||
|
availablePersonality.value = (() => {
|
||||||
|
const personalityList: typeof availablePersonality.value = {};
|
||||||
|
for (const personalityID of Object.values(gameConst.gameConst.availablePersonality)) {
|
||||||
|
personalityList[personalityID] = unwrap(gameConst.iActionInfo.personality[personalityID]);
|
||||||
|
}
|
||||||
|
personalityList["Random"] = {
|
||||||
|
value: "Random",
|
||||||
|
name: "???",
|
||||||
|
info: "무작위 성격을 선택합니다.",
|
||||||
|
};
|
||||||
|
return personalityList;
|
||||||
|
})();
|
||||||
|
|
||||||
|
stats.value = {
|
||||||
|
min: gameConst.gameConst.defaultStatMin,
|
||||||
|
max: gameConst.gameConst.defaultStatMax,
|
||||||
|
total: gameConst.gameConst.defaultStatTotal,
|
||||||
|
bonusMin: gameConst.gameConst.defaultStatMin,
|
||||||
|
bonusMax: gameConst.gameConst.defaultStatMax,
|
||||||
|
}
|
||||||
|
|
||||||
|
args.value = {
|
||||||
|
name: member.name,
|
||||||
|
leadership: stats.value.total - 2 * Math.floor(stats.value.total / 3),
|
||||||
|
strength: Math.floor(stats.value.total / 3),
|
||||||
|
intel: Math.floor(stats.value.total / 3),
|
||||||
|
pic: true,
|
||||||
|
character: "Random",
|
||||||
|
|
||||||
|
inheritCity: undefined,
|
||||||
|
inheritBonusStat: [0, 0, 0],
|
||||||
|
inheritSpecial: undefined,
|
||||||
|
inheritTurntime: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
gameConstStore.value = await getGameConstStore();
|
||||||
|
});
|
||||||
|
|
||||||
|
function randStatRandom() {
|
||||||
|
if (args.value === undefined) throw "nyc";
|
||||||
|
[args.value.leadership, args.value.strength, args.value.intel] = abilityRand(stats.value);
|
||||||
|
}
|
||||||
|
function randStatLeadPow() {
|
||||||
|
if (args.value === undefined) throw "nyc";
|
||||||
|
[args.value.leadership, args.value.strength, args.value.intel] = abilityLeadpow(stats.value);
|
||||||
|
}
|
||||||
|
function randStatLeadInt() {
|
||||||
|
if (args.value === undefined) throw "nyc";
|
||||||
|
[args.value.leadership, args.value.strength, args.value.intel] = abilityLeadint(stats.value);
|
||||||
|
}
|
||||||
|
function randStatPowInt() {
|
||||||
|
if (args.value === undefined) throw "nyc";
|
||||||
|
[args.value.leadership, args.value.strength, args.value.intel] = abilityPowint(stats.value);
|
||||||
|
}
|
||||||
|
function resetArgs() {
|
||||||
|
if (!args.value) throw "nyc";
|
||||||
|
const defaultStatTotal = stats.value.total;
|
||||||
|
args.value.name = member.name;
|
||||||
|
args.value.pic = true;
|
||||||
|
args.value.character = "Random";
|
||||||
|
args.value.leadership = defaultStatTotal - 2 * Math.floor(defaultStatTotal / 3);
|
||||||
|
args.value.strength = Math.floor(defaultStatTotal / 3);
|
||||||
|
args.value.intel = Math.floor(defaultStatTotal / 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
type APIArgs = {
|
async function submitForm() {
|
||||||
name: string;
|
if (!args.value) throw "nyc";
|
||||||
leadership: number;
|
//검증은 언제 되어야 하는가?
|
||||||
strength: number;
|
const subbmitArgs = args.value;
|
||||||
intel: number;
|
const totalStat = subbmitArgs.leadership + subbmitArgs.strength + subbmitArgs.intel;
|
||||||
pic: boolean;
|
const defaultStatTotal = stats.value.total;
|
||||||
character: string;
|
|
||||||
inheritSpecial?: string;
|
|
||||||
inheritTurntime?: number;
|
|
||||||
inheritCity?: number;
|
|
||||||
inheritBonusStat?: [number, number, number];
|
|
||||||
};
|
|
||||||
|
|
||||||
export default defineComponent({
|
if (totalStat < defaultStatTotal) {
|
||||||
name: "PageJoin",
|
if (
|
||||||
components: {
|
!confirm(
|
||||||
TopBackBar,
|
`설정한 능력치가 ${totalStat}으로, 실제 최대치인 ${defaultStatTotal}보다 적습니다.\r\n그래도 진행할까요?`
|
||||||
NumberInputWithInfo,
|
)
|
||||||
},
|
) {
|
||||||
data() {
|
return false;
|
||||||
const displayTable = JSON.parse(
|
}
|
||||||
localStorage.getItem(`conf.${serverID}.join.displayTable`) ?? "true"
|
}
|
||||||
);
|
try {
|
||||||
const displayInherit = JSON.parse(
|
await SammoAPI.General.Join(subbmitArgs);
|
||||||
localStorage.getItem(`conf.${serverID}.join.displayInherit`) ?? "true"
|
} catch (e) {
|
||||||
);
|
console.error(e);
|
||||||
const nationListShuffled = shuffle(nationList);
|
alert(`실패했습니다: ${e}`);
|
||||||
const args: APIArgs = {
|
return;
|
||||||
name: member.name,
|
}
|
||||||
leadership: stats.total - 2 * Math.floor(stats.total / 3),
|
|
||||||
strength: Math.floor(stats.total / 3),
|
|
||||||
intel: Math.floor(stats.total / 3),
|
|
||||||
pic: true,
|
|
||||||
character: "Random",
|
|
||||||
|
|
||||||
inheritCity: undefined,
|
alert("정상적으로 생성되었습니다. \n위키와 팁/강좌 게시판을 꼭 읽어보세요!");
|
||||||
inheritBonusStat: [0, 0, 0],
|
location.href = "./";
|
||||||
inheritSpecial: undefined,
|
}
|
||||||
inheritTurntime: undefined,
|
|
||||||
};
|
|
||||||
availableInheritCity.sort((lhs, rhs) => {
|
|
||||||
const rC = lhs[1].localeCompare(rhs[1]);
|
|
||||||
if (rC != 0) return rC;
|
|
||||||
return lhs[2].localeCompare(rhs[2]);
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
displayTable,
|
|
||||||
displayInherit,
|
|
||||||
availablePersonality,
|
|
||||||
availableInheritSpecial,
|
|
||||||
availableInheritCity,
|
|
||||||
member: member,
|
|
||||||
stats,
|
|
||||||
args,
|
|
||||||
nationList: nationListShuffled,
|
|
||||||
isBrightColor,
|
|
||||||
inheritTotalPoint,
|
|
||||||
inheritTurnTimeSet: false,
|
|
||||||
inheritTurnTimeMinute: 0,
|
|
||||||
inheritTurnTimeSecond: 0,
|
|
||||||
turnterm,
|
|
||||||
toggleZoom: true,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
displayTable(newValue: boolean) {
|
|
||||||
localStorage.setItem(
|
|
||||||
`conf.${serverID}.join.displayTable`,
|
|
||||||
JSON.stringify(newValue)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
displayInherit(newValue: boolean) {
|
|
||||||
localStorage.setItem(
|
|
||||||
`conf.${serverID}.join.displayInherit`,
|
|
||||||
JSON.stringify(newValue)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
inheritTurnTimeMinute(newValue: number) {
|
|
||||||
if (!this.inheritTurnTimeSet) {
|
|
||||||
this.args.inheritTurntime = undefined;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.args.inheritTurntime = newValue * 60 + this.inheritTurnTimeSecond;
|
|
||||||
},
|
|
||||||
inheritTurnTimeSecond(newValue: number) {
|
|
||||||
if (!this.inheritTurnTimeSet) {
|
|
||||||
this.args.inheritTurntime = undefined;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.args.inheritTurntime = this.inheritTurnTimeMinute * 60 + newValue;
|
|
||||||
},
|
|
||||||
inheritTurnTimeSet(newValue: boolean) {
|
|
||||||
if (!newValue) {
|
|
||||||
this.args.inheritTurntime = undefined;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.args.inheritTurntime =
|
|
||||||
this.inheritTurnTimeMinute * 60 + this.inheritTurnTimeSecond;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
iconPath() {
|
|
||||||
if (this.args.pic) {
|
|
||||||
return getIconPath(this.member.imgsvr, this.member.picture);
|
|
||||||
}
|
|
||||||
return getIconPath(0, "default.jpg");
|
|
||||||
},
|
|
||||||
inheritRequiredPoint() {
|
|
||||||
let inheritRequiredPoint = 0;
|
|
||||||
if (this.args.inheritCity !== undefined) {
|
|
||||||
inheritRequiredPoint += inheritPoints.city;
|
|
||||||
}
|
|
||||||
if (this.args.inheritSpecial !== undefined) {
|
|
||||||
inheritRequiredPoint += inheritPoints.special;
|
|
||||||
}
|
|
||||||
if (this.args.inheritTurntime !== undefined) {
|
|
||||||
inheritRequiredPoint += inheritPoints.turnTime;
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
this.args.inheritBonusStat !== undefined &&
|
|
||||||
sum(this.args.inheritBonusStat) != 0
|
|
||||||
) {
|
|
||||||
inheritRequiredPoint += inheritPoints.stat;
|
|
||||||
}
|
|
||||||
return inheritRequiredPoint;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
randStatRandom() {
|
|
||||||
[this.args.leadership, this.args.strength, this.args.intel] =
|
|
||||||
abilityRand();
|
|
||||||
},
|
|
||||||
randStatLeadPow() {
|
|
||||||
[this.args.leadership, this.args.strength, this.args.intel] =
|
|
||||||
abilityLeadpow();
|
|
||||||
},
|
|
||||||
randStatLeadInt() {
|
|
||||||
[this.args.leadership, this.args.strength, this.args.intel] =
|
|
||||||
abilityLeadint();
|
|
||||||
},
|
|
||||||
randStatPowInt() {
|
|
||||||
[this.args.leadership, this.args.strength, this.args.intel] =
|
|
||||||
abilityPowint();
|
|
||||||
},
|
|
||||||
resetArgs() {
|
|
||||||
this.args.name = member.name;
|
|
||||||
this.args.pic = true;
|
|
||||||
this.args.character = "Random";
|
|
||||||
this.args.leadership = stats.total - 2 * Math.floor(stats.total / 3);
|
|
||||||
this.args.strength = Math.floor(stats.total / 3);
|
|
||||||
this.args.intel = Math.floor(stats.total / 3);
|
|
||||||
},
|
|
||||||
async submitForm() {
|
|
||||||
//검증은 언제 되어야 하는가?
|
|
||||||
const args = clone(this.args);
|
|
||||||
const totalStat = args.leadership + args.strength + args.intel;
|
|
||||||
|
|
||||||
if (totalStat < stats.total) {
|
const iconPath = computed(() => {
|
||||||
if (!confirm(`설정한 능력치가 ${totalStat}으로, 실제 최대치인 ${stats.total}보다 적습니다.\r\n그래도 진행할까요?`)) {
|
if (!args.value) throw "nyc";
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
await SammoAPI.General.Join(args);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
alert(`실패했습니다: ${e}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
alert(
|
if (args.value.pic) {
|
||||||
"정상적으로 생성되었습니다. \n위키와 팁/강좌 게시판을 꼭 읽어보세요!"
|
return getIconPath(member.imgsvr, member.picture);
|
||||||
);
|
}
|
||||||
location.href = "./";
|
return getIconPath(0, "default.jpg");
|
||||||
},
|
});
|
||||||
},
|
|
||||||
|
const inheritRequiredPoint = computed(() => {
|
||||||
|
if (!args.value || !gameConstStore.value) throw "nyc";
|
||||||
|
|
||||||
|
let inheritRequiredPoint = 0;
|
||||||
|
const gameConst = gameConstStore.value.gameConst;
|
||||||
|
|
||||||
|
if (args.value.inheritCity !== undefined) {
|
||||||
|
inheritRequiredPoint += gameConst.inheritBornCityPoint;
|
||||||
|
}
|
||||||
|
if (args.value.inheritSpecial !== undefined) {
|
||||||
|
inheritRequiredPoint += gameConst.inheritBornSpecialPoint;
|
||||||
|
}
|
||||||
|
if (args.value.inheritTurntime !== undefined) {
|
||||||
|
inheritRequiredPoint += gameConst.inheritBornTurntimePoint;
|
||||||
|
}
|
||||||
|
if (args.value.inheritBonusStat !== undefined && sum(args.value.inheritBonusStat) != 0) {
|
||||||
|
inheritRequiredPoint += gameConst.inheritBornStatPoint;
|
||||||
|
}
|
||||||
|
return inheritRequiredPoint;
|
||||||
|
});
|
||||||
|
|
||||||
|
const toggleZoom = ref(true);
|
||||||
|
|
||||||
|
const displayTable = ref<boolean>(JSON.parse(localStorage.getItem(`conf.${serverID}.join.displayTable`) ?? "true"));
|
||||||
|
watch(displayTable, (newValue: boolean) => {
|
||||||
|
localStorage.setItem(`conf.${serverID}.join.displayTable`, JSON.stringify(newValue));
|
||||||
|
});
|
||||||
|
|
||||||
|
const displayInherit = ref<boolean>(JSON.parse(localStorage.getItem(`conf.${serverID}.join.displayInherit`) ?? "true"));
|
||||||
|
watch(displayInherit, (newValue: boolean) => {
|
||||||
|
localStorage.setItem(`conf.${serverID}.join.displayInherit`, JSON.stringify(newValue));
|
||||||
|
});
|
||||||
|
|
||||||
|
const inheritTurnTimeSet = ref(false);
|
||||||
|
watch(inheritTurnTimeSet, (newValue: boolean) => {
|
||||||
|
if (!args.value) throw "nyc";
|
||||||
|
|
||||||
|
if (!newValue) {
|
||||||
|
args.value.inheritTurntime = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
args.value.inheritTurntime = inheritTurnTimeMinute.value * 60 + inheritTurnTimeSecond.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
const inheritTurnTimeMinute = ref(0);
|
||||||
|
watch(inheritTurnTimeMinute, (newValue: number) => {
|
||||||
|
if (!args.value) throw "nyc";
|
||||||
|
if (!inheritTurnTimeSet.value) {
|
||||||
|
args.value.inheritTurntime = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
args.value.inheritTurntime = newValue * 60 + inheritTurnTimeSecond.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
const inheritTurnTimeSecond = ref(0);
|
||||||
|
watch(inheritTurnTimeSecond, (newValue: number) => {
|
||||||
|
if (!args.value) throw "nyc";
|
||||||
|
|
||||||
|
if (!inheritTurnTimeSet.value) {
|
||||||
|
args.value.inheritTurntime = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
args.value.inheritTurntime = inheritTurnTimeMinute.value * 60 + newValue;
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@@ -612,4 +594,4 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
+83
-198
@@ -3,7 +3,7 @@
|
|||||||
<BContainer
|
<BContainer
|
||||||
id="container"
|
id="container"
|
||||||
class="tb_layout bg0"
|
class="tb_layout bg0"
|
||||||
:toast="{root: true}"
|
:toast="{ root: true }"
|
||||||
:style="{ maxWidth: '1000px', margin: 'auto', border: 'solid 1px #888888', padding: '0' }"
|
:style="{ maxWidth: '1000px', margin: 'auto', border: 'solid 1px #888888', padding: '0' }"
|
||||||
>
|
>
|
||||||
<div class="bg1 section_bar">국가 정책</div>
|
<div class="bg1 section_bar">국가 정책</div>
|
||||||
@@ -17,94 +17,54 @@
|
|||||||
<div class="form_list row row-cols-md-2 row-cols-1">
|
<div class="form_list row row-cols-md-2 row-cols-1">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo v-model="nationPolicy.reqNationGold" :step="100" title="국가 권장 금">
|
<NumberInputWithInfo v-model="nationPolicy.reqNationGold" :step="100" title="국가 권장 금">
|
||||||
이보다 많으면 포상, 적으면 몰수/헌납합니다.(긴급포상
|
이보다 많으면 포상, 적으면 몰수/헌납합니다.(긴급포상 제외)
|
||||||
제외)
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo v-model="nationPolicy.reqNationRice" :step="100" title="국가 권장 쌀">
|
<NumberInputWithInfo v-model="nationPolicy.reqNationRice" :step="100" title="국가 권장 쌀">
|
||||||
이보다 많으면 포상, 적으면 몰수/헌납합니다.(긴급포상
|
이보다 많으면 포상, 적으면 몰수/헌납합니다.(긴급포상 제외)
|
||||||
제외)
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo
|
<NumberInputWithInfo v-model="nationPolicy.reqHumanWarUrgentGold" :step="100" title="유저전투장 긴급포상 금">
|
||||||
v-model="nationPolicy.reqHumanWarUrgentGold"
|
|
||||||
:step="100"
|
|
||||||
title="유저전투장 긴급포상 금"
|
|
||||||
>
|
|
||||||
유저장긴급포상시 이보다 금이 적은 장수에게 포상합니다.
|
유저장긴급포상시 이보다 금이 적은 장수에게 포상합니다.
|
||||||
<br />
|
<br />
|
||||||
0이면
|
0이면 보병 6회 징병({{ (defaultStatMax * 100).toLocaleString() }} * 6) 가능한 금을 기준으로 하며, 그 수치는
|
||||||
보병 6회 징병({{ (defaultStatMax * 100).toLocaleString() }} * 6)
|
현재 {{ zeroPolicy.reqHumanWarUrgentGold.toLocaleString() }}입니다.
|
||||||
가능한 금을 기준으로 하며, 그 수치는 현재
|
|
||||||
{{
|
|
||||||
zeroPolicy.reqHumanWarUrgentGold.toLocaleString()
|
|
||||||
}}입니다.
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo
|
<NumberInputWithInfo v-model="nationPolicy.reqHumanWarUrgentRice" :step="100" title="유저전투장 긴급포상 쌀">
|
||||||
v-model="nationPolicy.reqHumanWarUrgentRice"
|
|
||||||
:step="100"
|
|
||||||
title="유저전투장 긴급포상 쌀"
|
|
||||||
>
|
|
||||||
유저장긴급포상시 이보다 쌀이 적은 장수에게 포상합니다.
|
유저장긴급포상시 이보다 쌀이 적은 장수에게 포상합니다.
|
||||||
<br />
|
<br />
|
||||||
0이면
|
0이면 기본 병종으로 {{ (defaultStatMax * 100).toLocaleString() }} * 6명 사살 가능한 쌀을 기준으로 하며, 그
|
||||||
기본 병종으로 {{ (defaultStatMax * 100).toLocaleString() }} * 6명 사살
|
수치는 현재 {{ zeroPolicy.reqHumanWarUrgentRice.toLocaleString() }}입니다.
|
||||||
가능한 쌀을 기준으로 하며, 그 수치는 현재
|
|
||||||
{{
|
|
||||||
zeroPolicy.reqHumanWarUrgentRice.toLocaleString()
|
|
||||||
}}입니다.
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo
|
<NumberInputWithInfo v-model="nationPolicy.reqHumanWarRecommandGold" :step="100" title="유저전투장 권장 금">
|
||||||
v-model="nationPolicy.reqHumanWarRecommandGold"
|
|
||||||
:step="100"
|
|
||||||
title="유저전투장 권장 금"
|
|
||||||
>
|
|
||||||
유저전투장에게 주는 금입니다. 이보다 적으면 포상합니다.
|
유저전투장에게 주는 금입니다. 이보다 적으면 포상합니다.
|
||||||
<br />
|
<br />
|
||||||
0이면 유저전투장 긴급포상 금의 2배를 기준으로 하며, 그 수치는 현재
|
0이면 유저전투장 긴급포상 금의 2배를 기준으로 하며, 그 수치는 현재
|
||||||
{{
|
{{ (calcPolicyValue("reqHumanWarUrgentGold") * 2).toLocaleString() }}입니다.
|
||||||
(calcPolicyValue("reqHumanWarUrgentGold") * 2).toLocaleString()
|
|
||||||
}}입니다.
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo
|
<NumberInputWithInfo v-model="nationPolicy.reqHumanWarRecommandRice" :step="100" title="유저전투장 권장 쌀">
|
||||||
v-model="nationPolicy.reqHumanWarRecommandRice"
|
|
||||||
:step="100"
|
|
||||||
title="유저전투장 권장 쌀"
|
|
||||||
>
|
|
||||||
유저전투장에게 주는 쌀입니다. 이보다 적으면 포상합니다.
|
유저전투장에게 주는 쌀입니다. 이보다 적으면 포상합니다.
|
||||||
<br />
|
<br />
|
||||||
0이면 유저전투장 긴급포상 쌀의 2배를 기준으로 하며, 그 수치는 현재
|
0이면 유저전투장 긴급포상 쌀의 2배를 기준으로 하며, 그 수치는 현재
|
||||||
{{
|
{{ (calcPolicyValue("reqHumanWarUrgentRice") * 2).toLocaleString() }}입니다.
|
||||||
(calcPolicyValue("reqHumanWarUrgentRice") * 2).toLocaleString()
|
|
||||||
}}입니다.
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo
|
<NumberInputWithInfo v-model="nationPolicy.reqHumanDevelGold" :step="100" title="유저내정장 권장 금">
|
||||||
v-model="nationPolicy.reqHumanDevelGold"
|
유저내정장에게 주는 금입니다. 이보다 적으면 포상합니다.
|
||||||
:step="100"
|
|
||||||
title="유저내정장 권장 금"
|
|
||||||
>
|
|
||||||
유저내정장에게 주는 금입니다. 이보다 적으면
|
|
||||||
포상합니다.
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo
|
<NumberInputWithInfo v-model="nationPolicy.reqHumanDevelRice" :step="100" title="유저내정장 권장 쌀">
|
||||||
v-model="nationPolicy.reqHumanDevelRice"
|
유저내정장에게 주는 쌀입니다. 이보다 적으면 포상합니다.
|
||||||
:step="100"
|
|
||||||
title="유저내정장 권장 쌀"
|
|
||||||
>
|
|
||||||
유저내정장에게 주는 쌀입니다. 이보다 적으면
|
|
||||||
포상합니다.
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@@ -113,9 +73,7 @@
|
|||||||
<br />
|
<br />
|
||||||
0이면 기본 병종 4회({{ (defaultStatNPCMax * 100).toLocaleString() }}
|
0이면 기본 병종 4회({{ (defaultStatNPCMax * 100).toLocaleString() }}
|
||||||
* 4) 징병비를 기준으로 하며, 그 수치는 현재
|
* 4) 징병비를 기준으로 하며, 그 수치는 현재
|
||||||
{{
|
{{ zeroPolicy.reqNPCWarGold.toLocaleString() }}입니다.
|
||||||
zeroPolicy.reqNPCWarGold.toLocaleString()
|
|
||||||
}}입니다.
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@@ -123,26 +81,21 @@
|
|||||||
NPC전투장에게 주는 쌀입니다. 이보다 적으면 포상합니다.
|
NPC전투장에게 주는 쌀입니다. 이보다 적으면 포상합니다.
|
||||||
<br />
|
<br />
|
||||||
0이면 기본 병종으로
|
0이면 기본 병종으로
|
||||||
{{ (defaultStatNPCMax * 100).toLocaleString() }} * 4명 사살 가능한
|
{{ (defaultStatNPCMax * 100).toLocaleString() }} * 4명 사살 가능한 쌀을 기준으로 하며, 그 수치는 현재
|
||||||
쌀을 기준으로 하며, 그 수치는 현재
|
{{ zeroPolicy.reqNPCWarRice.toLocaleString() }}입니다.
|
||||||
{{
|
|
||||||
zeroPolicy.reqNPCWarRice.toLocaleString()
|
|
||||||
}}입니다.
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo v-model="nationPolicy.reqNPCDevelGold" :step="100" title="NPC내정장 권장 금">
|
<NumberInputWithInfo v-model="nationPolicy.reqNPCDevelGold" :step="100" title="NPC내정장 권장 금">
|
||||||
NPC내정장에게 주는 금입니다. 이보다 5배 더 많다면 헌납합니다.
|
NPC내정장에게 주는 금입니다. 이보다 5배 더 많다면 헌납합니다.
|
||||||
<br />
|
<br />
|
||||||
0이면
|
0이면 30턴 내정 가능한 금을 기준으로 하며, 그 수치는 현재
|
||||||
30턴 내정 가능한 금을 기준으로 하며, 그 수치는 현재
|
|
||||||
{{ zeroPolicy.reqNPCDevelGold }}입니다.
|
{{ zeroPolicy.reqNPCDevelGold }}입니다.
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo v-model="nationPolicy.reqNPCDevelRice" :step="100" title="NPC내정장 권장 쌀">
|
<NumberInputWithInfo v-model="nationPolicy.reqNPCDevelRice" :step="100" title="NPC내정장 권장 쌀">
|
||||||
NPC내정장에게 주는 쌀입니다. 이보다 5배 더 많다면
|
NPC내정장에게 주는 쌀입니다. 이보다 5배 더 많다면 헌납합니다.
|
||||||
헌납합니다.
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@@ -150,21 +103,23 @@
|
|||||||
v-model="nationPolicy.minimumResourceActionAmount"
|
v-model="nationPolicy.minimumResourceActionAmount"
|
||||||
:step="100"
|
:step="100"
|
||||||
title="포상/몰수/헌납/삼/팜 최소 단위"
|
title="포상/몰수/헌납/삼/팜 최소 단위"
|
||||||
>연산결과가 이 단위보다 적다면 수행하지 않습니다.</NumberInputWithInfo>
|
>
|
||||||
|
연산결과가 이 단위보다 적다면 수행하지 않습니다.
|
||||||
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo
|
<NumberInputWithInfo
|
||||||
v-model="nationPolicy.maximumResourceActionAmount"
|
v-model="nationPolicy.maximumResourceActionAmount"
|
||||||
:step="100"
|
:step="100"
|
||||||
title="포상/몰수/헌납/삼/팜 최대 단위"
|
title="포상/몰수/헌납/삼/팜 최대 단위"
|
||||||
>연산결과가 이 단위보다 크다면, 이 값에 맞춥니다.</NumberInputWithInfo>
|
>
|
||||||
|
연산결과가 이 단위보다 크다면, 이 값에 맞춥니다.
|
||||||
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo
|
<NumberInputWithInfo v-model="nationPolicy.minWarCrew" :step="50" title="최소 전투 가능 병력 수">
|
||||||
v-model="nationPolicy.minWarCrew"
|
이보다 적을 때에는 징병을 시도합니다.
|
||||||
:step="50"
|
</NumberInputWithInfo>
|
||||||
title="최소 전투 가능 병력 수"
|
|
||||||
>이보다 적을 때에는 징병을 시도합니다.</NumberInputWithInfo>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo
|
<NumberInputWithInfo
|
||||||
@@ -172,38 +127,27 @@
|
|||||||
:step="100"
|
:step="100"
|
||||||
title="NPC 최소 징병 가능 인구 수"
|
title="NPC 최소 징병 가능 인구 수"
|
||||||
>
|
>
|
||||||
도시의 인구가 이보다 낮으면 NPC는 도시에서 징병하지 않고 후방
|
도시의 인구가 이보다 낮으면 NPC는 도시에서 징병하지 않고 후방 워프합니다.
|
||||||
워프합니다.
|
<br />NPC의 최대 병력수보다 낮게 설정하면 제자리에서 정착장려를 합니다.
|
||||||
<br />NPC의 최대 병력수보다 낮게 설정하면 제자리에서
|
|
||||||
정착장려를 합니다.
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo
|
<NumberInputWithInfo
|
||||||
:modelValue="nationPolicy.safeRecruitCityPopulationRatio * 100"
|
:modelValue="nationPolicy.safeRecruitCityPopulationRatio * 100"
|
||||||
@update:modelValue="
|
|
||||||
nationPolicy.safeRecruitCityPopulationRatio = $event / 100
|
|
||||||
"
|
|
||||||
:step="0.5"
|
:step="0.5"
|
||||||
:int="false"
|
:int="false"
|
||||||
:min="0"
|
:min="0"
|
||||||
:max="100"
|
:max="100"
|
||||||
title="제자리 징병 허용 인구율(%)"
|
title="제자리 징병 허용 인구율(%)"
|
||||||
|
@update:modelValue="nationPolicy.safeRecruitCityPopulationRatio = $event / 100"
|
||||||
>
|
>
|
||||||
전쟁 시 후방 발령, 후방 워프의 기준 인구입니다. 이보다 많다면
|
전쟁 시 후방 발령, 후방 워프의 기준 인구입니다. 이보다 많다면 '충분하다'고 판단합니다.
|
||||||
'충분하다'고 판단합니다.
|
<br />NPC의 최대 병력수보다 낮게 설정하면 제자리에서 정착장려를 합니다.
|
||||||
<br />NPC의 최대 병력수보다 낮게 설정하면
|
|
||||||
제자리에서 정착장려를 합니다.
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<NumberInputWithInfo
|
<NumberInputWithInfo v-model="nationPolicy.minNPCWarLeadership" :step="5" title="NPC 전투 참여 통솔 기준">
|
||||||
v-model="nationPolicy.minNPCWarLeadership"
|
이 수치보다 같거나 높으면 NPC전투장으로 분류됩니다.
|
||||||
:step="5"
|
|
||||||
title="NPC 전투 참여 통솔 기준"
|
|
||||||
>
|
|
||||||
이 수치보다 같거나 높으면 NPC전투장으로
|
|
||||||
분류됩니다.
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@@ -214,44 +158,27 @@
|
|||||||
:max="100"
|
:max="100"
|
||||||
title="훈련/사기진작 목표치"
|
title="훈련/사기진작 목표치"
|
||||||
>
|
>
|
||||||
훈련/사기진작 기준치입니다. 이보다 같거나 높으면
|
훈련/사기진작 기준치입니다. 이보다 같거나 높으면 출병합니다.
|
||||||
출병합니다.
|
|
||||||
</NumberInputWithInfo>
|
</NumberInputWithInfo>
|
||||||
</div>
|
</div>
|
||||||
<!--allowNpcAttackCity는 현재 게임 내 비활성-->
|
<!--allowNpcAttackCity는 현재 게임 내 비활성-->
|
||||||
</div>
|
</div>
|
||||||
<div style="padding: 0 8pt">
|
<div style="padding: 0 8pt">
|
||||||
<div class="alert alert-secondary">
|
<div class="alert alert-secondary">
|
||||||
전투 부대는 작업중입니다(json양식:
|
전투 부대는 작업중입니다(json양식: {부대번호:[시작도시번호(아국),도착도시번호(적군)],...})
|
||||||
{부대번호:[시작도시번호(아국),도착도시번호(적군)],...})
|
<br />후방 징병 부대는 작업중입니다(json양식: [부대번호,...]) <br />내정 부대는 작업중입니다(json양식:
|
||||||
<br />후방 징병 부대는 작업중입니다(json양식: [부대번호,...])
|
[부대번호,...])
|
||||||
<br />내정 부대는 작업중입니다(json양식: [부대번호,...])
|
<input id="CombatForce" type="hidden" :value="JSON.stringify(nationPolicy.CombatForce)" data-type="json" />
|
||||||
<input
|
<input id="SupportForce" type="hidden" :value="JSON.stringify(nationPolicy.SupportForce)" data-type="json" />
|
||||||
type="hidden"
|
<input id="DevelopForce" type="hidden" :value="JSON.stringify(nationPolicy.DevelopForce)" data-type="json" />
|
||||||
:value="JSON.stringify(nationPolicy.CombatForce)"
|
|
||||||
data-type="json"
|
|
||||||
id="CombatForce"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="hidden"
|
|
||||||
:value="JSON.stringify(nationPolicy.SupportForce)"
|
|
||||||
data-type="json"
|
|
||||||
id="SupportForce"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="hidden"
|
|
||||||
:value="JSON.stringify(nationPolicy.DevelopForce)"
|
|
||||||
data-type="json"
|
|
||||||
id="DevelopForce"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control_bar" data-type="nationPolicy">
|
<div class="control_bar" data-type="nationPolicy">
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group">
|
||||||
<button type="button" @click="resetPolicy" class="btn btn-dark reset_btn">초기값으로</button>
|
<button type="button" class="btn btn-dark reset_btn" @click="resetPolicy">초기값으로</button>
|
||||||
<button type="button" @click="rollbackPolicy" class="btn btn-secondary revert_btn">이전값으로</button>
|
<button type="button" class="btn btn-secondary revert_btn" @click="rollbackPolicy">이전값으로</button>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" @click="submitPolicy" class="btn btn-primary submit_btn">설정</button>
|
<button type="button" class="btn btn-primary submit_btn" @click="submitPolicy">설정</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="row row-cols-md-2 row-cols-1 g-0">
|
<div class="row row-cols-md-2 row-cols-1 g-0">
|
||||||
<div class="col half_section_left">
|
<div class="col half_section_left">
|
||||||
@@ -266,8 +193,7 @@
|
|||||||
<div class="text-left px-2">
|
<div class="text-left px-2">
|
||||||
<small class="text-muted">
|
<small class="text-muted">
|
||||||
예턴이 없거나, 지정되어 있더라도 실패하면
|
예턴이 없거나, 지정되어 있더라도 실패하면
|
||||||
<br />아래 순위에 따라
|
<br />아래 순위에 따라 사령턴을 시도합니다.
|
||||||
사령턴을 시도합니다.
|
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -285,16 +211,14 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #item="{ element }">
|
<template #item="{ element }">
|
||||||
<div class="list-group-item">
|
<div class="list-group-item">
|
||||||
<i class="bi bi-list"></i>
|
<i class="bi bi-list" />
|
||||||
{{
|
{{ element.id }}
|
||||||
element.id
|
|
||||||
}}
|
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
|
||||||
v-b-tooltip.hover
|
v-b-tooltip.hover
|
||||||
|
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
||||||
:title="actionHelpText[element.id]"
|
:title="actionHelpText[element.id]"
|
||||||
>
|
>
|
||||||
<i class="bi bi-question-lg"></i>
|
<i class="bi bi-question-lg" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -310,16 +234,14 @@
|
|||||||
>
|
>
|
||||||
<template #item="{ element }">
|
<template #item="{ element }">
|
||||||
<div class="list-group-item">
|
<div class="list-group-item">
|
||||||
<i class="bi bi-list"></i>
|
<i class="bi bi-list" />
|
||||||
{{
|
{{ element.id }}
|
||||||
element.id
|
|
||||||
}}
|
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
|
||||||
v-b-tooltip.hover
|
v-b-tooltip.hover
|
||||||
|
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
||||||
:title="actionHelpText[element.id]"
|
:title="actionHelpText[element.id]"
|
||||||
>
|
>
|
||||||
<i class="bi bi-question-lg"></i>
|
<i class="bi bi-question-lg" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -328,22 +250,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="control_bar" data-type="nationPriority">
|
<div class="control_bar" data-type="nationPriority">
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group">
|
||||||
<button
|
<button type="button" class="btn btn-dark reset_btn" @click="resetNationPriority">초기값으로</button>
|
||||||
type="button"
|
<button type="button" class="btn btn-secondary revert_btn" @click="rollbackNationPriority">
|
||||||
class="btn btn-dark reset_btn"
|
이전값으로
|
||||||
@click="resetNationPriority"
|
</button>
|
||||||
>초기값으로</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-secondary revert_btn"
|
|
||||||
@click="rollbackNationPriority"
|
|
||||||
>이전값으로</button>
|
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button type="button" class="btn btn-primary submit_btn" @click="submitNationPriority">설정</button>
|
||||||
type="button"
|
|
||||||
class="btn btn-primary submit_btn"
|
|
||||||
@click="submitNationPriority"
|
|
||||||
>설정</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -359,8 +271,7 @@
|
|||||||
<div class="text-left px-2">
|
<div class="text-left px-2">
|
||||||
<small class="text-muted">
|
<small class="text-muted">
|
||||||
순위가 높은 것부터 시도합니다.
|
순위가 높은 것부터 시도합니다.
|
||||||
<br />아무것도 실행할 수 없으면
|
<br />아무것도 실행할 수 없으면 물자조달이나 인재탐색을 합니다.
|
||||||
물자조달이나 인재탐색을 합니다.
|
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -378,16 +289,14 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #item="{ element }">
|
<template #item="{ element }">
|
||||||
<div class="list-group-item">
|
<div class="list-group-item">
|
||||||
<i class="bi bi-list"></i>
|
<i class="bi bi-list" />
|
||||||
{{
|
{{ element.id }}
|
||||||
element.id
|
|
||||||
}}
|
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
|
||||||
v-b-tooltip.hover
|
v-b-tooltip.hover
|
||||||
|
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
||||||
:title="actionHelpText[element.id]"
|
:title="actionHelpText[element.id]"
|
||||||
>
|
>
|
||||||
<i class="bi bi-question-lg"></i>
|
<i class="bi bi-question-lg" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -403,16 +312,14 @@
|
|||||||
>
|
>
|
||||||
<template #item="{ element }">
|
<template #item="{ element }">
|
||||||
<div class="list-group-item">
|
<div class="list-group-item">
|
||||||
<i class="bi bi-list"></i>
|
<i class="bi bi-list" />
|
||||||
{{
|
{{ element.id }}
|
||||||
element.id
|
|
||||||
}}
|
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
|
||||||
v-b-tooltip.hover
|
v-b-tooltip.hover
|
||||||
|
class="btn btn-sm float-right btn-secondary py-0 px-1"
|
||||||
:title="actionHelpText[element.id]"
|
:title="actionHelpText[element.id]"
|
||||||
>
|
>
|
||||||
<i class="bi bi-question-lg"></i>
|
<i class="bi bi-question-lg" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -421,22 +328,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="control_bar" data-type="generalPriority">
|
<div class="control_bar" data-type="generalPriority">
|
||||||
<div class="btn-group" role="group">
|
<div class="btn-group" role="group">
|
||||||
<button
|
<button type="button" class="btn btn-dark reset_btn" @click="resetGeneralPriority">초기값으로</button>
|
||||||
type="button"
|
<button type="button" class="btn btn-secondary revert_btn" @click="rollbackGeneralPriority">
|
||||||
class="btn btn-dark reset_btn"
|
이전값으로
|
||||||
@click="resetGeneralPriority"
|
</button>
|
||||||
>초기값으로</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-secondary revert_btn"
|
|
||||||
@click="rollbackGeneralPriority"
|
|
||||||
>이전값으로</button>
|
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button type="button" class="btn btn-primary submit_btn" @click="submitGeneralPriority">설정</button>
|
||||||
type="button"
|
|
||||||
class="btn btn-primary submit_btn"
|
|
||||||
@click="submitGeneralPriority"
|
|
||||||
>설정</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -444,7 +341,6 @@
|
|||||||
</BContainer>
|
</BContainer>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
||||||
type SetterInfo = {
|
type SetterInfo = {
|
||||||
setter: string | null;
|
setter: string | null;
|
||||||
date: string | null;
|
date: string | null;
|
||||||
@@ -480,13 +376,7 @@ import "@scss/common/bootstrap5.scss";
|
|||||||
import "@scss/game_bg.scss";
|
import "@scss/game_bg.scss";
|
||||||
|
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import {
|
import type { IDItem, InvalidResponse, NationPolicy, NPCChiefActions, NPCGeneralActions } from "@/defs";
|
||||||
IDItem,
|
|
||||||
InvalidResponse,
|
|
||||||
NationPolicy,
|
|
||||||
NPCChiefActions,
|
|
||||||
NPCGeneralActions,
|
|
||||||
} from "@/defs";
|
|
||||||
import NumberInputWithInfo from "@/components/NumberInputWithInfo.vue";
|
import NumberInputWithInfo from "@/components/NumberInputWithInfo.vue";
|
||||||
import { cloneDeep, isEqual, isNumber, last } from "lodash";
|
import { cloneDeep, isEqual, isNumber, last } from "lodash";
|
||||||
import { unwrap } from "@util/unwrap";
|
import { unwrap } from "@util/unwrap";
|
||||||
@@ -496,8 +386,7 @@ import { NPCPriorityBtnHelpMessage } from "@/helpTexts";
|
|||||||
import draggable from "vuedraggable";
|
import draggable from "vuedraggable";
|
||||||
import TopBackBar from "@/components/TopBackBar.vue";
|
import TopBackBar from "@/components/TopBackBar.vue";
|
||||||
import { convertIDArray } from "@util/convertIDArray";
|
import { convertIDArray } from "@util/convertIDArray";
|
||||||
import { useToast } from 'bootstrap-vue-3/src/components/BToast/plugin';
|
import { useToast, BContainer } from "bootstrap-vue-3";
|
||||||
import BContainer from "bootstrap-vue-3/src/components/BContainer.vue";
|
|
||||||
|
|
||||||
const chiefActionPriority = ref<IDItem<NPCChiefActions>[]>([]);
|
const chiefActionPriority = ref<IDItem<NPCChiefActions>[]>([]);
|
||||||
const chiefActionKeys = ref(new Set(staticValues.availableNationPriorityItems));
|
const chiefActionKeys = ref(new Set(staticValues.availableNationPriorityItems));
|
||||||
@@ -534,8 +423,8 @@ function resetPolicy() {
|
|||||||
}
|
}
|
||||||
nationPolicy.value = cloneDeep(staticValues.defaultNationPolicy);
|
nationPolicy.value = cloneDeep(staticValues.defaultNationPolicy);
|
||||||
toasts.info({
|
toasts.info({
|
||||||
title: '초기화 완료',
|
title: "초기화 완료",
|
||||||
body: "서버 초기값을 적용했습니다.설정 버튼을 누르면 반영됩니다."
|
body: "서버 초기값을 적용했습니다.설정 버튼을 누르면 반영됩니다.",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,9 +486,7 @@ async function submitPolicy() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function calcPolicyValue(
|
function calcPolicyValue(title: keyof NationPolicy): number {
|
||||||
title: keyof NationPolicy
|
|
||||||
): number {
|
|
||||||
if (!(title in nationPolicy.value)) {
|
if (!(title in nationPolicy.value)) {
|
||||||
throw `${title}이 NationPolicy key가 아님`;
|
throw `${title}이 NationPolicy key가 아님`;
|
||||||
}
|
}
|
||||||
@@ -746,9 +633,7 @@ async function submitGeneralPriority() {
|
|||||||
method: "post",
|
method: "post",
|
||||||
data: convertFormData({
|
data: convertFormData({
|
||||||
type: "generalPriority",
|
type: "generalPriority",
|
||||||
data: JSON.stringify(
|
data: JSON.stringify(generalActionPriority.value.map(({ id }) => id)),
|
||||||
generalActionPriority.value.map(({ id }) => id)
|
|
||||||
),
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
const result: InvalidResponse = response.data;
|
const result: InvalidResponse = response.data;
|
||||||
@@ -829,4 +714,4 @@ async function submitGeneralPriority() {
|
|||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,27 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<BContainer id="container" :toast="{ root: true }" class="pageNationBetting bg0">
|
<BContainer id="container" :toast="{ root: true }" class="pageNationBetting bg0">
|
||||||
<TopBackBar :title="title" />
|
<TopBackBar :title="title" />
|
||||||
<BettingDetail
|
<BettingDetail v-if="targetBettingID !== undefined" :bettingID="targetBettingID" @reqToast="addToast" />
|
||||||
v-if="targetBettingID !== undefined"
|
|
||||||
:bettingID="targetBettingID"
|
|
||||||
@reqToast="addToast"
|
|
||||||
/>
|
|
||||||
<div v-if="bettingList === undefined">로딩 중...</div>
|
<div v-if="bettingList === undefined">로딩 중...</div>
|
||||||
<div class="bettingList" v-else>
|
<div v-else class="bettingList">
|
||||||
<div class="bg2">베팅 목록</div>
|
<div class="bg2">베팅 목록</div>
|
||||||
<div
|
<div
|
||||||
class="bettingItem"
|
|
||||||
v-for="info of Object.values(bettingList).reverse()"
|
v-for="info of Object.values(bettingList).reverse()"
|
||||||
:key="info.id"
|
:key="info.id"
|
||||||
|
class="bettingItem"
|
||||||
@click="targetBettingID = info.id"
|
@click="targetBettingID = info.id"
|
||||||
>
|
>
|
||||||
[{{ parseYearMonth(info.openYearMonth)[0] }}년 {{ parseYearMonth(info.openYearMonth)[1] }}월] {{ info.name }}
|
[{{ parseYearMonth(info.openYearMonth)[0] }}년 {{ parseYearMonth(info.openYearMonth)[1] }}월] {{ info.name }}
|
||||||
<span
|
<span v-if="info.finished">(종료)</span>
|
||||||
v-if="info.finished"
|
<span v-else-if="(yearMonth ?? 0) <= info.closeYearMonth"
|
||||||
>(종료)</span>
|
>({{ parseYearMonth(info.closeYearMonth)[0] }}년 {{ parseYearMonth(info.closeYearMonth)[1] }}월까지)</span
|
||||||
<span
|
>
|
||||||
v-else-if="(yearMonth ?? 0) <= info.closeYearMonth"
|
|
||||||
>({{ parseYearMonth(info.closeYearMonth)[0] }}년 {{ parseYearMonth(info.closeYearMonth)[1] }}월까지)</span>
|
|
||||||
<span v-else>(베팅 마감)</span>
|
<span v-else>(베팅 마감)</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -33,42 +27,35 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import TopBackBar from "@/components/TopBackBar.vue";
|
import TopBackBar from "@/components/TopBackBar.vue";
|
||||||
import BottomBar from "@/components/BottomBar.vue";
|
import BottomBar from "@/components/BottomBar.vue";
|
||||||
import { BettingInfo, ToastType } from "@/defs";
|
import type { ToastType } from "@/defs";
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import { SammoAPI, ValidResponse } from "./SammoAPI";
|
import { SammoAPI } from "./SammoAPI";
|
||||||
import { isString } from "lodash";
|
import { isString } from "lodash";
|
||||||
import { parseYearMonth } from "@/util/parseYearMonth";
|
import { parseYearMonth } from "@/util/parseYearMonth";
|
||||||
import { joinYearMonth } from "./util/joinYearMonth";
|
import { joinYearMonth } from "./util/joinYearMonth";
|
||||||
import BettingDetail from "@/components/BettingDetail.vue";
|
import BettingDetail from "@/components/BettingDetail.vue";
|
||||||
import { useToast } from "bootstrap-vue-3/src/components/BToast/plugin";
|
import { BContainer, useToast } from "bootstrap-vue-3";
|
||||||
import { unwrap } from "./util/unwrap";
|
import { unwrap } from "./util/unwrap";
|
||||||
import BContainer from "bootstrap-vue-3/src/components/BContainer.vue";
|
import type { BettingListResponse } from "./defs/API/Betting";
|
||||||
|
|
||||||
|
|
||||||
type BettingListResponse = ValidResponse & {
|
|
||||||
bettingList: Record<number, Omit<BettingInfo & { totalAmount: number }, 'candidates'>>,
|
|
||||||
year: number,
|
|
||||||
month: number,
|
|
||||||
};
|
|
||||||
|
|
||||||
const toasts = unwrap(useToast());
|
const toasts = unwrap(useToast());
|
||||||
const year = ref<number>();
|
const year = ref<number>();
|
||||||
const month = ref<number>();
|
const month = ref<number>();
|
||||||
const yearMonth = ref<number>();
|
const yearMonth = ref<number>();
|
||||||
const bettingList = ref<BettingListResponse['bettingList']>();
|
const bettingList = ref<BettingListResponse["bettingList"]>();
|
||||||
|
|
||||||
|
|
||||||
const targetBettingID = ref<number>();
|
const targetBettingID = ref<number>();
|
||||||
|
|
||||||
|
|
||||||
function addToast(msg: ToastType) {
|
function addToast(msg: ToastType) {
|
||||||
toasts.show(msg.content, msg.options);
|
toasts.show(msg.content, msg.options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("시작!");
|
||||||
console.log('시작!');
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
try {
|
try {
|
||||||
const result = await SammoAPI.Betting.GetBettingList<BettingListResponse>();
|
const result = await SammoAPI.Betting.GetBettingList();
|
||||||
year.value = result.year;
|
year.value = result.year;
|
||||||
month.value = result.month;
|
month.value = result.month;
|
||||||
yearMonth.value = joinYearMonth(result.year, result.month);
|
yearMonth.value = joinYearMonth(result.year, result.month);
|
||||||
@@ -85,8 +72,5 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const title = "국가 베팅장";
|
||||||
const title = '국가 베팅장';
|
</script>
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
<template>
|
||||||
|
<BContainer id="container" :toast="{ root: true }" class="pageNationGeneral bg0">
|
||||||
|
<TopBackBar :title="title" :reloadable="true" @reload="reload" :teleport-zone="toolbarID" />
|
||||||
|
<!-- eslint-disable-next-line vue/max-attributes-per-line -->
|
||||||
|
<GeneralList
|
||||||
|
v-if="asyncReady"
|
||||||
|
:list="generalList"
|
||||||
|
:troops="troopList"
|
||||||
|
:env="envVal"
|
||||||
|
:toolbarID="toolbarID"
|
||||||
|
role="pageNationGeneral"
|
||||||
|
:height="'fill'"
|
||||||
|
:availableGeneralClick="true"
|
||||||
|
@generalClick="openBattleCenter"
|
||||||
|
/>
|
||||||
|
<!--<BottomBar />-->
|
||||||
|
</BContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
/*declare const staticValues: {
|
||||||
|
serverNick: string,
|
||||||
|
mapName: string,
|
||||||
|
unitSet: string,
|
||||||
|
};*/
|
||||||
|
</script>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import TopBackBar from "@/components/TopBackBar.vue";
|
||||||
|
//import BottomBar from "@/components/BottomBar.vue";
|
||||||
|
import { BContainer } from "bootstrap-vue-3";
|
||||||
|
import { onMounted, provide, ref } from "vue";
|
||||||
|
import { SammoAPI } from "./SammoAPI";
|
||||||
|
import { merge2DArrToObjectArr } from "./util/merge2DArrToObjectArr";
|
||||||
|
import type { GeneralListItem, GeneralListResponse } from "./defs/API/Nation";
|
||||||
|
import GeneralList from "./components/GeneralList.vue";
|
||||||
|
import { type GameConstStore, getGameConstStore } from "./GameConstStore";
|
||||||
|
|
||||||
|
const generalList = ref<GeneralListItem[]>([]);
|
||||||
|
const troopList = ref<Record<number, string>>({});
|
||||||
|
const envVal = ref<GeneralListResponse["env"]>({
|
||||||
|
year: 1,
|
||||||
|
month: 1,
|
||||||
|
turnterm: 1,
|
||||||
|
turntime: "2022-02-22 22:22:22.22222",
|
||||||
|
killturn: 80,
|
||||||
|
});
|
||||||
|
|
||||||
|
const toolbarID = "toolbar-id";
|
||||||
|
|
||||||
|
const gameConstStore = ref<GameConstStore>();
|
||||||
|
provide("gameConstStore", gameConstStore);
|
||||||
|
|
||||||
|
const asyncReady = ref(false);
|
||||||
|
|
||||||
|
const title = "세력 장수";
|
||||||
|
|
||||||
|
const storeP = getGameConstStore().then((store) => {
|
||||||
|
gameConstStore.value = store;
|
||||||
|
});
|
||||||
|
|
||||||
|
void Promise.all([storeP]).then(() => {
|
||||||
|
asyncReady.value = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
async function reload() {
|
||||||
|
try {
|
||||||
|
const { column, list, permission, troops, env } = await SammoAPI.Nation.GeneralList();
|
||||||
|
troopList.value = {};
|
||||||
|
//XXX: 로직상 똑같은데....
|
||||||
|
if (permission == 0) {
|
||||||
|
const rawGeneralList = merge2DArrToObjectArr(column, list);
|
||||||
|
generalList.value = rawGeneralList.map((v) => {
|
||||||
|
return { permission, st0: true, st1: false, st2: false, ...v };
|
||||||
|
});
|
||||||
|
} else if (permission == 1) {
|
||||||
|
const rawGeneralList = merge2DArrToObjectArr(column, list);
|
||||||
|
generalList.value = rawGeneralList.map((v) => {
|
||||||
|
return { permission, st0: true, st1: true, st2: false, ...v };
|
||||||
|
});
|
||||||
|
} else if ([2, 3, 4].includes(permission)) {
|
||||||
|
const rawGeneralList = merge2DArrToObjectArr(column, list);
|
||||||
|
generalList.value = rawGeneralList.map((v) => {
|
||||||
|
return { permission, st0: true, st1: true, st2: true, ...v };
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const [troopLeader, troopName] of troops) {
|
||||||
|
troopList.value[troopLeader] = troopName;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw `?? ${permission}`;
|
||||||
|
}
|
||||||
|
envVal.value = env;
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openBattleCenter(generalID: number){
|
||||||
|
window.open(`b_battleCenter.php?gen=${generalID}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await reload();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
#app {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pageNationGeneral {
|
||||||
|
display: grid;
|
||||||
|
//grid-template-rows: auto 1fr auto;
|
||||||
|
grid-template-rows: auto 1fr;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
+48
-120
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<BContainer :toast="{root: true}" id="container" class="pageNationStratFinan bg0">
|
<BContainer id="container" :toast="{ root: true }" class="pageNationStratFinan bg0">
|
||||||
<TopBackBar title="내무부" />
|
<TopBackBar title="내무부" />
|
||||||
<div class="diplomacyTitle">외교관계</div>
|
<div class="diplomacyTitle">외교관계</div>
|
||||||
<div class="diplomacyTable">
|
<div class="diplomacyTable">
|
||||||
@@ -12,11 +12,7 @@
|
|||||||
<div>기간</div>
|
<div>기간</div>
|
||||||
<div>종료 시점</div>
|
<div>종료 시점</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-for="nation in nationsList" :key="nation.nation" :class="['diplomacyItem', 'tRow', 's-border-b']">
|
||||||
:class="['diplomacyItem', 'tRow', 's-border-b']"
|
|
||||||
v-for="nation in nationsList"
|
|
||||||
:key="nation.nation"
|
|
||||||
>
|
|
||||||
<div :class="`sam-nation-bg-${nation.color.slice(1)}`">
|
<div :class="`sam-nation-bg-${nation.color.slice(1)}`">
|
||||||
{{ nation.name }}
|
{{ nation.name }}
|
||||||
</div>
|
</div>
|
||||||
@@ -29,28 +25,21 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<div
|
<div
|
||||||
:style="{
|
:style="{
|
||||||
color:
|
color: diplomacyStateInfo[nation.diplomacy.state].color ?? undefined,
|
||||||
diplomacyStateInfo[nation.diplomacy.state].color ?? undefined,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ diplomacyStateInfo[nation.diplomacy.state].name }}
|
{{ diplomacyStateInfo[nation.diplomacy.state].name }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{{
|
{{ nation.diplomacy.term == 0 ? "-" : `${nation.diplomacy.term}개월` }}
|
||||||
nation.diplomacy.term == 0 ? "-" : `${nation.diplomacy.term}개월`
|
|
||||||
}}
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-for="([endYear, endMonth], _idx) in [
|
v-for="([endYear, endMonth], _idx) in [
|
||||||
parseYearMonth(
|
parseYearMonth(joinYearMonth(year, month) + (nation.diplomacy.term ?? 0)),
|
||||||
joinYearMonth(year, month) + (nation.diplomacy.term??0)
|
|
||||||
),
|
|
||||||
]"
|
]"
|
||||||
:key="_idx"
|
:key="_idx"
|
||||||
>
|
>
|
||||||
{{
|
{{ nation.diplomacy.term == 0 ? "-" : `${endYear}년 ${endMonth}월` }}
|
||||||
nation.diplomacy.term == 0 ? "-" : `${endYear}년 ${endMonth}월`
|
|
||||||
}}
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -60,19 +49,9 @@
|
|||||||
<div class="bg1" style="display: flex; justify-content: space-around">
|
<div class="bg1" style="display: flex; justify-content: space-around">
|
||||||
<div style="flex: 1 1 auto">국가 방침</div>
|
<div style="flex: 1 1 auto">국가 방침</div>
|
||||||
<div>
|
<div>
|
||||||
<b-button
|
<b-button v-if="editable && !inEditNationMsg" @click="enableEditNationMsg"> 국가방침 수정 </b-button>
|
||||||
@click="enableEditNationMsg"
|
<b-button v-if="editable && inEditNationMsg" @click="saveNationMsg"> 저장 </b-button>
|
||||||
v-if="editable && !inEditNationMsg"
|
<b-button v-if="editable && inEditNationMsg" @click="rollbackNationMsg"> 취소 </b-button>
|
||||||
>국가방침 수정</b-button
|
|
||||||
>
|
|
||||||
<b-button @click="saveNationMsg" v-if="editable && inEditNationMsg"
|
|
||||||
>저장</b-button
|
|
||||||
>
|
|
||||||
<b-button
|
|
||||||
v-if="editable && inEditNationMsg"
|
|
||||||
@click="rollbackNationMsg"
|
|
||||||
>취소</b-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<TipTap
|
<TipTap
|
||||||
@@ -87,22 +66,12 @@
|
|||||||
<div class="bg1" style="display: flex; justify-content: space-around">
|
<div class="bg1" style="display: flex; justify-content: space-around">
|
||||||
<div style="flex: 1 1 auto">임관 권유</div>
|
<div style="flex: 1 1 auto">임관 권유</div>
|
||||||
<div>
|
<div>
|
||||||
<b-button
|
<b-button v-if="editable && !inEditScoutMsg" @click="enableEditScoutMsg"> 임관 권유문 수정 </b-button>
|
||||||
@click="enableEditScoutMsg"
|
<b-button v-if="editable && inEditScoutMsg" @click="saveScoutMsg"> 저장 </b-button>
|
||||||
v-if="editable && !inEditScoutMsg"
|
<b-button v-if="editable && inEditScoutMsg" @click="rollbackScoutMsg"> 취소 </b-button>
|
||||||
>임관 권유문 수정</b-button
|
|
||||||
>
|
|
||||||
<b-button @click="saveScoutMsg" v-if="editable && inEditScoutMsg"
|
|
||||||
>저장</b-button
|
|
||||||
>
|
|
||||||
<b-button v-if="editable && inEditScoutMsg" @click="rollbackScoutMsg"
|
|
||||||
>취소</b-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="border-bottom: solid gray 0.5px">
|
<div style="border-bottom: solid gray 0.5px">870px x 200px를 넘어서는 내용은 표시되지 않습니다.</div>
|
||||||
870px x 200px를 넘어서는 내용은 표시되지 않습니다.
|
|
||||||
</div>
|
|
||||||
<div style="width: 870px; margin-left: auto">
|
<div style="width: 870px; margin-left: auto">
|
||||||
<TipTap
|
<TipTap
|
||||||
v-model="scoutMsg"
|
v-model="scoutMsg"
|
||||||
@@ -119,9 +88,13 @@
|
|||||||
<div class="row gx-0">
|
<div class="row gx-0">
|
||||||
<div class="col-12 bg2">자금 예산</div>
|
<div class="col-12 bg2">자금 예산</div>
|
||||||
<div class="col-4 bg1">현 재</div>
|
<div class="col-4 bg1">현 재</div>
|
||||||
<div class="col-8">{{ gold.toLocaleString() }}</div>
|
<div class="col-8">
|
||||||
|
{{ gold.toLocaleString() }}
|
||||||
|
</div>
|
||||||
<div class="col-4 bg1">단기수입</div>
|
<div class="col-4 bg1">단기수입</div>
|
||||||
<div class="col-8">{{ income.gold.war.toLocaleString() }}</div>
|
<div class="col-8">
|
||||||
|
{{ income.gold.war.toLocaleString() }}
|
||||||
|
</div>
|
||||||
<div class="col-4 bg1">세 금</div>
|
<div class="col-4 bg1">세 금</div>
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
{{ Math.floor(incomeGoldCity).toLocaleString() }}
|
{{ Math.floor(incomeGoldCity).toLocaleString() }}
|
||||||
@@ -134,8 +107,7 @@
|
|||||||
<div class="col-4 bg1">국고 예산</div>
|
<div class="col-4 bg1">국고 예산</div>
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
{{ Math.floor(gold + incomeGold - outcomeByBill).toLocaleString() }}
|
{{ Math.floor(gold + incomeGold - outcomeByBill).toLocaleString() }}
|
||||||
({{ incomeGold >= outcomeByBill ? "+" : ""
|
({{ incomeGold >= outcomeByBill ? "+" : "" }}{{ Math.floor(incomeGold - outcomeByBill).toLocaleString() }})
|
||||||
}}{{ Math.floor(incomeGold - outcomeByBill).toLocaleString() }})
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -143,7 +115,9 @@
|
|||||||
<div class="row gx-0">
|
<div class="row gx-0">
|
||||||
<div class="col-12 bg2">군량 예산</div>
|
<div class="col-12 bg2">군량 예산</div>
|
||||||
<div class="col-4 bg1">현 재</div>
|
<div class="col-4 bg1">현 재</div>
|
||||||
<div class="col-8">{{ rice.toLocaleString() }}</div>
|
<div class="col-8">
|
||||||
|
{{ rice.toLocaleString() }}
|
||||||
|
</div>
|
||||||
<div class="col-4 bg1">둔전수입</div>
|
<div class="col-4 bg1">둔전수입</div>
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
{{ Math.floor(incomeRiceWall).toLocaleString() }}
|
{{ Math.floor(incomeRiceWall).toLocaleString() }}
|
||||||
@@ -160,37 +134,27 @@
|
|||||||
<div class="col-4 bg1">국고 예산</div>
|
<div class="col-4 bg1">국고 예산</div>
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
{{ Math.floor(rice + incomeRice - outcomeByBill).toLocaleString() }}
|
{{ Math.floor(rice + incomeRice - outcomeByBill).toLocaleString() }}
|
||||||
({{ incomeRice >= outcomeByBill ? "+" : ""
|
({{ incomeRice >= outcomeByBill ? "+" : "" }}{{ Math.floor(incomeRice - outcomeByBill).toLocaleString() }})
|
||||||
}}{{ Math.floor(incomeRice - outcomeByBill).toLocaleString() }})
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<div class="row gx-0">
|
<div class="row gx-0">
|
||||||
<div class="col-4 bg1 d-grid">
|
<div class="col-4 bg1 d-grid">
|
||||||
<div class="align-self-center">
|
<div class="align-self-center">세율 <span class="avoid-wrap">(5 ~ 30%)</span></div>
|
||||||
세율 <span class="avoid-wrap">(5 ~ 30%)</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8 row gx-0">
|
<div class="col-8 row gx-0">
|
||||||
<div class="col-md-6 offset-md-3 align-self-center">
|
<div class="col-md-6 offset-md-3 align-self-center">
|
||||||
<div class="input-group my-0">
|
<div class="input-group my-0">
|
||||||
<input
|
<input
|
||||||
|
v-model="policy.rate"
|
||||||
type="number"
|
type="number"
|
||||||
class="form-control py-1 f_tnum px-0 text-end"
|
class="form-control py-1 f_tnum px-0 text-end"
|
||||||
v-model="policy.rate"
|
|
||||||
min="5"
|
min="5"
|
||||||
max="30"
|
max="30"
|
||||||
/><span class="input-group-text py-1 f_tnum">%</span
|
/><span class="input-group-text py-1 f_tnum">%</span
|
||||||
><b-button
|
><b-button v-if="editable" variant="primary" size="sm" @click="setRate"> 변경 </b-button
|
||||||
variant="primary"
|
><b-button v-if="editable" size="sm" @click="rollbackRate"> 취소 </b-button>
|
||||||
size="sm"
|
|
||||||
@click="setRate"
|
|
||||||
v-if="editable"
|
|
||||||
>변경</b-button
|
|
||||||
><b-button size="sm" @click="rollbackRate" v-if="editable"
|
|
||||||
>취소</b-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -199,29 +163,20 @@
|
|||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<div class="row gx-0">
|
<div class="row gx-0">
|
||||||
<div class="col-4 bg1 d-grid">
|
<div class="col-4 bg1 d-grid">
|
||||||
<div class="align-self-center">
|
<div class="align-self-center">지급률 <span class="avoid-wrap">(20 ~ 200%)</span></div>
|
||||||
지급률 <span class="avoid-wrap">(20 ~ 200%)</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8 row gx-0">
|
<div class="col-8 row gx-0">
|
||||||
<div class="col-md-6 offset-md-3 align-self-center">
|
<div class="col-md-6 offset-md-3 align-self-center">
|
||||||
<div class="input-group my-0">
|
<div class="input-group my-0">
|
||||||
<input
|
<input
|
||||||
|
v-model="policy.bill"
|
||||||
type="number"
|
type="number"
|
||||||
class="form-control py-1 f_tnum px-0 text-end"
|
class="form-control py-1 f_tnum px-0 text-end"
|
||||||
v-model="policy.bill"
|
|
||||||
min="20"
|
min="20"
|
||||||
max="200"
|
max="200"
|
||||||
/><span class="input-group-text py-1 f_tnum">%</span
|
/><span class="input-group-text py-1 f_tnum">%</span
|
||||||
><b-button
|
><b-button v-if="editable" variant="primary" size="sm" @click="setBill"> 변경 </b-button
|
||||||
variant="primary"
|
><b-button v-if="editable" size="sm" @click="rollbackBill"> 취소 </b-button>
|
||||||
size="sm"
|
|
||||||
@click="setBill"
|
|
||||||
v-if="editable"
|
|
||||||
>변경</b-button
|
|
||||||
><b-button size="sm" @click="rollbackBill" v-if="editable"
|
|
||||||
>취소</b-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -230,32 +185,20 @@
|
|||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<div class="row gx-0">
|
<div class="row gx-0">
|
||||||
<div class="col-4 bg1 d-grid">
|
<div class="col-4 bg1 d-grid">
|
||||||
<div class="align-self-center">
|
<div class="align-self-center">기밀 권한 <span class="avoid-wrap">(1 ~ 99년)</span></div>
|
||||||
기밀 권한 <span class="avoid-wrap">(1 ~ 99년)</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8 row gx-0">
|
<div class="col-8 row gx-0">
|
||||||
<div class="col-md-6 offset-md-3 align-self-center">
|
<div class="col-md-6 offset-md-3 align-self-center">
|
||||||
<div class="input-group my-0">
|
<div class="input-group my-0">
|
||||||
<input
|
<input
|
||||||
|
v-model="policy.secretLimit"
|
||||||
type="number"
|
type="number"
|
||||||
class="form-control py-1 f_tnum px-0 text-end"
|
class="form-control py-1 f_tnum px-0 text-end"
|
||||||
v-model="policy.secretLimit"
|
|
||||||
min="1"
|
min="1"
|
||||||
max="99"
|
max="99"
|
||||||
/><span class="input-group-text py-1 f_tnum">년</span
|
/><span class="input-group-text py-1 f_tnum">년</span
|
||||||
><b-button
|
><b-button v-if="editable" variant="primary" size="sm" @click="setSecretLimit"> 변경 </b-button
|
||||||
variant="primary"
|
><b-button v-if="editable" size="sm" @click="rollbackSecretLimit"> 취소 </b-button>
|
||||||
size="sm"
|
|
||||||
@click="setSecretLimit"
|
|
||||||
v-if="editable"
|
|
||||||
>변경</b-button
|
|
||||||
><b-button
|
|
||||||
size="sm"
|
|
||||||
@click="rollbackSecretLimit"
|
|
||||||
v-if="editable"
|
|
||||||
>취소</b-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -267,29 +210,23 @@
|
|||||||
<div class="align-self-center">전쟁 금지 설정</div>
|
<div class="align-self-center">전쟁 금지 설정</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8 d-grid">
|
<div class="col-8 d-grid">
|
||||||
<div class="align-self-center">{{warSettingCnt.remain}} 회(월 +{{warSettingCnt.inc}}회, 최대{{warSettingCnt.max}}회)</div>
|
<div class="align-self-center">
|
||||||
|
{{ warSettingCnt.remain }} 회(월 +{{ warSettingCnt.inc }}회, 최대{{ warSettingCnt.max }}회)
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3 col-md-4"></div>
|
<div class="col-3 col-md-4" />
|
||||||
<div class="col-3 col-md-2 row gx-0">
|
<div class="col-3 col-md-2 row gx-0">
|
||||||
<div class="col-9 col-md-8 text-end p-2">전쟁 금지</div>
|
<div class="col-9 col-md-8 text-end p-2">전쟁 금지</div>
|
||||||
<div class="col-3 col-md-4 py-2">
|
<div class="col-3 col-md-4 py-2">
|
||||||
<b-form-checkbox
|
<b-form-checkbox v-model="policy.blockWar" switch @change="setBlockWar" />
|
||||||
v-model="policy.blockWar"
|
|
||||||
@change="setBlockWar"
|
|
||||||
switch
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3 col-md-2 row gx-0">
|
<div class="col-3 col-md-2 row gx-0">
|
||||||
<div class="col-9 col-md-8 text-end p-2">임관 금지</div>
|
<div class="col-9 col-md-8 text-end p-2">임관 금지</div>
|
||||||
<div class="col-3 col-md-4 py-2">
|
<div class="col-3 col-md-4 py-2">
|
||||||
<b-form-checkbox
|
<b-form-checkbox v-model="policy.blockScout" switch @change="setBlockScout" />
|
||||||
v-model="policy.blockScout"
|
|
||||||
@change="setBlockScout"
|
|
||||||
switch
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -303,17 +240,11 @@ import TopBackBar from "@/components/TopBackBar.vue";
|
|||||||
import BottomBar from "@/components/BottomBar.vue";
|
import BottomBar from "@/components/BottomBar.vue";
|
||||||
import { computed, defineComponent, reactive, ref, toRefs } from "vue";
|
import { computed, defineComponent, reactive, ref, toRefs } from "vue";
|
||||||
import { isString } from "lodash";
|
import { isString } from "lodash";
|
||||||
import {
|
import { type diplomacyState, diplomacyStateInfo, type NationStaticItem } from "./defs";
|
||||||
diplomacyState,
|
|
||||||
diplomacyStateInfo,
|
|
||||||
NationStaticItem,
|
|
||||||
} from "./defs";
|
|
||||||
import { SammoAPI } from "./SammoAPI";
|
import { SammoAPI } from "./SammoAPI";
|
||||||
import { joinYearMonth } from "@/util/joinYearMonth";
|
import { joinYearMonth } from "@/util/joinYearMonth";
|
||||||
import { parseYearMonth } from "@/util/parseYearMonth";
|
import { parseYearMonth } from "@/util/parseYearMonth";
|
||||||
import { ValidResponse } from "./util/callSammoAPI";
|
import { useToast, BContainer } from "bootstrap-vue-3";
|
||||||
import BContainer from "bootstrap-vue-3/src/components/BContainer.vue";
|
|
||||||
import { useToast } from "bootstrap-vue-3/src/components/BToast/plugin";
|
|
||||||
import { unwrap } from "./util/unwrap";
|
import { unwrap } from "./util/unwrap";
|
||||||
|
|
||||||
type NationItem = NationStaticItem & {
|
type NationItem = NationStaticItem & {
|
||||||
@@ -324,9 +255,6 @@ type NationItem = NationStaticItem & {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
type SetBlockWarResponse = ValidResponse & {
|
|
||||||
availableCnt: number;
|
|
||||||
}
|
|
||||||
declare const staticValues: {
|
declare const staticValues: {
|
||||||
editable: boolean;
|
editable: boolean;
|
||||||
nationMsg: string;
|
nationMsg: string;
|
||||||
@@ -370,8 +298,8 @@ export default defineComponent({
|
|||||||
TopBackBar,
|
TopBackBar,
|
||||||
BottomBar,
|
BottomBar,
|
||||||
TipTap,
|
TipTap,
|
||||||
BContainer
|
BContainer,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const toasts = unwrap(useToast());
|
const toasts = unwrap(useToast());
|
||||||
const self = reactive(staticValues);
|
const self = reactive(staticValues);
|
||||||
@@ -569,7 +497,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
async function setBlockWar() {
|
async function setBlockWar() {
|
||||||
try {
|
try {
|
||||||
const result = await SammoAPI.Nation.SetBlockWar<SetBlockWarResponse>({ value: self.policy.blockWar });
|
const result = await SammoAPI.Nation.SetBlockWar({ value: self.policy.blockWar });
|
||||||
self.warSettingCnt.remain = result.availableCnt;
|
self.warSettingCnt.remain = result.availableCnt;
|
||||||
toasts.info({
|
toasts.info({
|
||||||
title: "변경",
|
title: "변경",
|
||||||
@@ -645,4 +573,4 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
methods: {},
|
methods: {},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
+653
-489
@@ -3,115 +3,193 @@
|
|||||||
<div class="col alert alert-dark m-0 p-1 center">
|
<div class="col alert alert-dark m-0 p-1 center">
|
||||||
<h4 class="m-0">명령 목록</h4>
|
<h4 class="m-0">명령 목록</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row gx-1">
|
<div class="row gx-1">
|
||||||
<div class="col d-grid">
|
<div class="col d-grid">
|
||||||
<b-dropdown left text="턴 선택">
|
<BButton variant="secondary" @click="isEditMode = !isEditMode">
|
||||||
<b-dropdown-item @click="selectTurn()">해제</b-dropdown-item>
|
{{ isEditMode ? "일반 모드로" : "고급 모드로" }}
|
||||||
<b-dropdown-item @click="selectAll(true)">모든턴</b-dropdown-item>
|
</BButton>
|
||||||
<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>
|
||||||
<div
|
<div
|
||||||
class="col alert alert-primary m-0 p-0"
|
class="col alert alert-primary m-0 p-0"
|
||||||
style="
|
style="text-align: center; display: flex; justify-content: center; align-items: center"
|
||||||
text-align: center;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
{{ serverNow }}
|
<SimpleClock :serverTime="serverNow" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col d-grid">
|
<div class="col d-grid">
|
||||||
<b-dropdown right text="반복">
|
<BDropdown right text="반복">
|
||||||
<b-dropdown-item
|
<BDropdownItem v-for="turnIdx in maxPushTurn" :key="turnIdx" @click="repeatGeneralCommand(turnIdx)">
|
||||||
v-for="turnIdx in maxPushTurn"
|
{{ turnIdx }}턴
|
||||||
:key="turnIdx"
|
</BDropdownItem>
|
||||||
@click="repeatGeneralCommand(turnIdx)"
|
</BDropdown>
|
||||||
>{{ turnIdx }}턴
|
|
||||||
</b-dropdown-item>
|
|
||||||
</b-dropdown>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="commandTable">
|
<div v-if="isEditMode" class="row gx-1">
|
||||||
|
<div class="col-4 d-grid">
|
||||||
|
<BDropdown left text="범위">
|
||||||
|
<BDropdownItem @click="queryActionHelper.selectTurn()"> 해제 </BDropdownItem>
|
||||||
|
<BDropdownItem @click="queryActionHelper.selectAll()"> 모든턴 </BDropdownItem>
|
||||||
|
<BDropdownItem @click="queryActionHelper.selectStep(0, 2)"> 홀수턴 </BDropdownItem>
|
||||||
|
<BDropdownItem @click="queryActionHelper.selectStep(1, 2)"> 짝수턴 </BDropdownItem>
|
||||||
|
<BDropdownDivider />
|
||||||
|
|
||||||
|
<BDropdownText v-for="spanIdx in [3, 4, 5, 6, 7]" :key="spanIdx">
|
||||||
|
{{ spanIdx }}턴 간격
|
||||||
|
<br />
|
||||||
|
<BButtonGroup>
|
||||||
|
<BButton
|
||||||
|
v-for="beginIdx in spanIdx"
|
||||||
|
:key="beginIdx"
|
||||||
|
class="ignoreMe"
|
||||||
|
@click="queryActionHelper.selectStep(beginIdx - 1, spanIdx)"
|
||||||
|
>
|
||||||
|
{{ beginIdx }}
|
||||||
|
</BButton>
|
||||||
|
</BButtonGroup>
|
||||||
|
</BDropdownText>
|
||||||
|
</BDropdown>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-4 d-grid">
|
||||||
|
<BDropdown left text="보관함">
|
||||||
|
<BDropdownItem
|
||||||
|
v-for="[actionKey, actions] of storedActions"
|
||||||
|
:key="actionKey"
|
||||||
|
@click.self="useStoredAction(actions)"
|
||||||
|
>
|
||||||
|
{{ actionKey }}
|
||||||
|
<BButton size="sm" @click.prevent="deleteStoredActions(actionKey)"> 삭제 </BButton>
|
||||||
|
</BDropdownItem>
|
||||||
|
</BDropdown>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-4 d-grid">
|
||||||
|
<BDropdown right text="최근 실행">
|
||||||
|
<BDropdownItem
|
||||||
|
v-for="(action, idx) of Array.from(recentActions.values()).reverse()"
|
||||||
|
:key="idx"
|
||||||
|
@click="void reserveCommandDirect([[queryActionHelper.getSelectedTurnList(), action]])"
|
||||||
|
>
|
||||||
|
{{ action.brief }}
|
||||||
|
</BDropdownItem>
|
||||||
|
</BDropdown>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-5 d-grid">
|
||||||
|
<BDropdown left variant="info" text="선택한 턴을">
|
||||||
|
<BDropdownItem @click="clipboardCut"> <i class="bi bi-scissors" /> 잘라내기 </BDropdownItem>
|
||||||
|
<BDropdownItem @click="clipboardCopy"> <i class="bi bi-files" /> 복사하기 </BDropdownItem>
|
||||||
|
<BDropdownItem @click="clipboardPaste"> <i class="bi bi-clipboard-fill" /> 붙여넣기 </BDropdownItem>
|
||||||
|
<BDropdownDivider />
|
||||||
|
<BDropdownItem @click="setStoredActions">
|
||||||
|
<i class="bi bi-bookmark-plus-fill" /> 보관하기
|
||||||
|
</BDropdownItem>
|
||||||
|
<BDropdownItem @click="subRepeatCommand"> <i class="bi bi-arrow-repeat" /> 반복하기 </BDropdownItem>
|
||||||
|
<BDropdownDivider />
|
||||||
|
<BDropdownItem @click="eraseSelectedTurnList"> <i class="bi bi-eraser" /> 비우기 </BDropdownItem>
|
||||||
|
<BDropdownItem @click="eraseAndPullCommand">
|
||||||
|
<i class="bi bi-arrow-bar-up" /> 지우고 당기기
|
||||||
|
</BDropdownItem>
|
||||||
|
<BDropdownItem @click="pushEmptyCommand"> <i class="bi bi-arrow-bar-down" /> 뒤로 밀기 </BDropdownItem>
|
||||||
|
<!-- 최근에 실행한 10턴 -->
|
||||||
|
</BDropdown>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-7 d-grid">
|
||||||
|
<BButton variant="light" :style="{ color: 'black' }" @click="toggleForm($event)"> 명령 선택 ▾ </BButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<CommandSelectForm
|
||||||
|
ref="commandSelectForm"
|
||||||
|
v-model:activatedCategory="activatedCategory"
|
||||||
|
:commandList="commandList"
|
||||||
|
@onClose="chooseCommand($event)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div :style="{ position: 'relative' }">
|
||||||
|
<div
|
||||||
|
class="bg-dark"
|
||||||
|
:style="{
|
||||||
|
position: 'absolute',
|
||||||
|
top: `${basicModeRowHeight * currentQuickReserveTarget + 30}px`,
|
||||||
|
width: '100%',
|
||||||
|
zIndex: 9,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<CommandSelectForm
|
||||||
|
ref="commandQuickReserveForm"
|
||||||
|
v-model:activatedCategory="activatedCategory"
|
||||||
|
:commandList="commandList"
|
||||||
|
:hideClose="false"
|
||||||
|
@onClose="chooseQuickReserveCommand($event)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
:class="{
|
||||||
|
commandTable: true,
|
||||||
|
isEditMode,
|
||||||
|
}"
|
||||||
|
>
|
||||||
<DragSelect
|
<DragSelect
|
||||||
|
v-slot="{ selected }"
|
||||||
:style="rowGridStyle"
|
:style="rowGridStyle"
|
||||||
|
:disabled="!isEditMode"
|
||||||
attribute="turnIdx"
|
attribute="turnIdx"
|
||||||
@dragStart="isDragToggle = true"
|
@dragStart="isDragToggle = true"
|
||||||
@dragDone="
|
@dragDone="
|
||||||
isDragToggle = false;
|
isDragToggle = false;
|
||||||
toggleTurn(...$event);
|
queryActionHelper.toggleTurn(...$event);
|
||||||
"
|
"
|
||||||
v-slot="{ selected }"
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="(turnObj, turnIdx) in reservedCommandList.slice(
|
v-for="(turnObj, turnIdx) in reservedCommandList.slice(0, viewMaxTurn)"
|
||||||
0,
|
|
||||||
viewMaxTurn
|
|
||||||
)"
|
|
||||||
:turnIdx="turnIdx"
|
|
||||||
:key="turnIdx"
|
:key="turnIdx"
|
||||||
|
:turnIdx="turnIdx"
|
||||||
class="idx_pad center d-grid"
|
class="idx_pad center d-grid"
|
||||||
>
|
>
|
||||||
<b-button
|
<BButton
|
||||||
|
v-if="isEditMode"
|
||||||
size="sm"
|
size="sm"
|
||||||
:variant="
|
:variant="
|
||||||
(isDragToggle && selected.has(`${turnIdx}`))?'light':
|
isDragToggle && selected.has(`${turnIdx}`)
|
||||||
turnList.has(turnIdx)
|
? 'light'
|
||||||
|
: selectedTurnList.has(turnIdx)
|
||||||
? 'info'
|
? 'info'
|
||||||
: turnList.size == 0 && prevTurnList.has(turnIdx)
|
: selectedTurnList.size == 0 && prevSelectedTurnList.has(turnIdx)
|
||||||
? 'success'
|
? 'success'
|
||||||
: 'primary'
|
: 'primary'
|
||||||
"
|
"
|
||||||
>{{ turnIdx + 1 }}</b-button
|
|
||||||
>
|
>
|
||||||
|
{{ turnIdx + 1 }}
|
||||||
|
</BButton>
|
||||||
|
<div v-else class="plain-center">
|
||||||
|
{{ turnIdx + 1 }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</DragSelect>
|
</DragSelect>
|
||||||
<DragSelect
|
<DragSelect
|
||||||
|
v-slot="{ selected }"
|
||||||
:style="rowGridStyle"
|
:style="rowGridStyle"
|
||||||
attribute="turnIdx"
|
attribute="turnIdx"
|
||||||
|
:disabled="!isEditMode"
|
||||||
@dragStart="isDragSingle = true"
|
@dragStart="isDragSingle = true"
|
||||||
@dragDone="
|
@dragDone="
|
||||||
isDragSingle = false;
|
isDragSingle = false;
|
||||||
selectTurn(...$event);
|
queryActionHelper.selectTurn(...$event);
|
||||||
"
|
"
|
||||||
v-slot="{ selected }"
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="(turnObj, turnIdx) in reservedCommandList.slice(
|
v-for="(turnObj, turnIdx) in reservedCommandList.slice(0, viewMaxTurn)"
|
||||||
0,
|
|
||||||
viewMaxTurn
|
|
||||||
)"
|
|
||||||
:key="turnIdx"
|
:key="turnIdx"
|
||||||
height="24"
|
height="24"
|
||||||
class="month_pad center"
|
class="month_pad center"
|
||||||
:turnIdx="turnIdx"
|
:turnIdx="turnIdx"
|
||||||
:style="{
|
:style="{
|
||||||
'white-space': 'nowrap',
|
'white-space': 'nowrap',
|
||||||
'font-size': `${Math.min(
|
'font-size': `${Math.min(14, (75 / (`${turnObj.year ?? 1}`.length + 8)) * 1.8)}px`,
|
||||||
14,
|
|
||||||
(75 / (`${turnObj.year ?? 1}`.length + 8)) * 1.8
|
|
||||||
)}px`,
|
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
color:
|
color: isDragSingle && selected.has(`${turnIdx}`) ? 'cyan' : undefined,
|
||||||
isDragSingle && selected.has(`${turnIdx}`) ? 'cyan' : undefined,
|
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ turnObj.year ? `${turnObj.year}年` : "" }}
|
{{ turnObj.year ? `${turnObj.year}年` : "" }}
|
||||||
@@ -120,10 +198,7 @@
|
|||||||
</DragSelect>
|
</DragSelect>
|
||||||
<div :style="rowGridStyle">
|
<div :style="rowGridStyle">
|
||||||
<div
|
<div
|
||||||
v-for="(turnObj, turnIdx) in reservedCommandList.slice(
|
v-for="(turnObj, turnIdx) in reservedCommandList.slice(0, viewMaxTurn)"
|
||||||
0,
|
|
||||||
viewMaxTurn
|
|
||||||
)"
|
|
||||||
:key="turnIdx"
|
:key="turnIdx"
|
||||||
class="time_pad center"
|
class="time_pad center"
|
||||||
:style="{
|
:style="{
|
||||||
@@ -137,176 +212,98 @@
|
|||||||
</div>
|
</div>
|
||||||
<div :style="rowGridStyle">
|
<div :style="rowGridStyle">
|
||||||
<div
|
<div
|
||||||
v-for="(turnObj, turnIdx) in reservedCommandList.slice(
|
v-for="(turnObj, turnIdx) in reservedCommandList.slice(0, viewMaxTurn)"
|
||||||
0,
|
|
||||||
viewMaxTurn
|
|
||||||
)"
|
|
||||||
:key="turnIdx"
|
:key="turnIdx"
|
||||||
class="turn_pad center"
|
class="turn_pad center"
|
||||||
@click="chooseCommand(turnObj.action)"
|
|
||||||
>
|
>
|
||||||
<span
|
<span v-b-tooltip.hover class="turn_text" :style="turnObj.style" :title="turnObj.tooltip">
|
||||||
class="turn_text"
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
:style="turnObj.style"
|
<span v-html="turnObj.brief" />
|
||||||
v-b-tooltip.hover
|
</span>
|
||||||
:title="turnObj.tooltip"
|
</div>
|
||||||
v-html="turnObj.brief"
|
</div>
|
||||||
></span>
|
<div v-if="!isEditMode" :style="rowGridStyle">
|
||||||
|
<div
|
||||||
|
v-for="(turnObj, turnIdx) in reservedCommandList.slice(0, viewMaxTurn)"
|
||||||
|
:key="turnIdx"
|
||||||
|
class="action_pad d-grid"
|
||||||
|
>
|
||||||
|
<BButton
|
||||||
|
:variant="turnIdx % 2 == 0 ? 'secondary' : 'dark'"
|
||||||
|
size="sm"
|
||||||
|
class="simple_action_btn bi bi-pencil"
|
||||||
|
@click="toggleQuickReserveForm(turnIdx)"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row gx-1">
|
<div class="row gx-1">
|
||||||
<div class="col d-grid">
|
<div class="col d-grid">
|
||||||
<b-dropdown right split text="당기기" @click="pullGeneralCommandSingle">
|
<BDropdown :split="isEditMode" text="당기기" @click="pullGeneralCommandSingle">
|
||||||
<b-dropdown-item
|
<BDropdownItem v-for="turnIdx in maxPushTurn" :key="turnIdx" @click="pushGeneralCommand(-turnIdx)">
|
||||||
v-for="turnIdx in maxPushTurn"
|
{{ turnIdx }}턴
|
||||||
:key="turnIdx"
|
</BDropdownItem>
|
||||||
@click="pushGeneralCommand(-turnIdx)"
|
</BDropdown>
|
||||||
>{{ turnIdx }}턴
|
|
||||||
</b-dropdown-item>
|
|
||||||
</b-dropdown>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col d-grid">
|
<div class="col d-grid">
|
||||||
<b-dropdown right split text="미루기" @click="pushGeneralCommandSingle">
|
<BDropdown :split="isEditMode" text="미루기" @click="pushGeneralCommandSingle">
|
||||||
<b-dropdown-item
|
<BDropdownItem v-for="turnIdx in maxPushTurn" :key="turnIdx" @click="pushGeneralCommand(turnIdx)">
|
||||||
v-for="turnIdx in maxPushTurn"
|
{{ turnIdx }}턴
|
||||||
:key="turnIdx"
|
</BDropdownItem>
|
||||||
@click="pushGeneralCommand(turnIdx)"
|
</BDropdown>
|
||||||
>{{ turnIdx }}턴
|
|
||||||
</b-dropdown-item>
|
|
||||||
</b-dropdown>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col d-grid">
|
<div class="col d-grid">
|
||||||
<b-button @click="toggleViewMaxTurn">{{
|
<BButton @click="toggleViewMaxTurn">
|
||||||
flippedMaxTurn == viewMaxTurn ? "펼치기" : "접기"
|
{{ flippedMaxTurn == viewMaxTurn ? "펼치기" : "접기" }}
|
||||||
}}</b-button>
|
</BButton>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row gx-0">
|
|
||||||
<div class="col-2 d-grid">
|
|
||||||
<b-button
|
|
||||||
:pressed="searchModeOn"
|
|
||||||
@click="toggleSearchCommand()"
|
|
||||||
:variant="searchModeOn ? 'info' : 'primary'"
|
|
||||||
v-b-tooltip.hover
|
|
||||||
title="검색 기능을 활성화합니다."
|
|
||||||
><i class="bi bi-search"></i
|
|
||||||
></b-button>
|
|
||||||
</div>
|
|
||||||
<div class="col-7">
|
|
||||||
<v-multiselect
|
|
||||||
v-model="selectedCommand"
|
|
||||||
:allow-empty="false"
|
|
||||||
:options="commandList"
|
|
||||||
:group-select="false"
|
|
||||||
group-values="values"
|
|
||||||
group-label="category"
|
|
||||||
label="searchText"
|
|
||||||
track-by="value"
|
|
||||||
open-direction="top"
|
|
||||||
:show-labels="false"
|
|
||||||
selectLabel="선택(엔터)"
|
|
||||||
selectGroupLabel=""
|
|
||||||
selectedLabel="선택됨"
|
|
||||||
deselectLabel="해제(엔터)"
|
|
||||||
deselectGroupLabel=""
|
|
||||||
placeholder="턴 선택"
|
|
||||||
:maxHeight="400"
|
|
||||||
:searchable="searchModeOn"
|
|
||||||
>
|
|
||||||
<template v-slot:noResult>검색 결과가 없습니다.</template>
|
|
||||||
<template v-slot:option="props"
|
|
||||||
><!--FIXME: 카테고리-->
|
|
||||||
<template v-if="props.option.title">
|
|
||||||
<span
|
|
||||||
class="compensatePositive"
|
|
||||||
v-if="props.option.compensation > 0"
|
|
||||||
>▲</span
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="compensateNegative"
|
|
||||||
v-else-if="props.option.compensation < 0"
|
|
||||||
>▼</span
|
|
||||||
>
|
|
||||||
<span class="compensateNeutral" v-else></span>
|
|
||||||
<span :class="[props.option.possible ? '' : 'commandImpossible']">
|
|
||||||
{{ props.option.title }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="props.option.category">
|
|
||||||
{{ props.option.category }}
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
<template v-slot:singleLabel="props">
|
|
||||||
{{ props.option.simpleName }}
|
|
||||||
</template>
|
|
||||||
</v-multiselect>
|
|
||||||
</div>
|
|
||||||
<div class="col-3 d-grid">
|
|
||||||
<b-button @click="reserveCommand()" variant="primary">실행</b-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import addMilliseconds from "date-fns/esm/addMilliseconds";
|
declare const staticValues: {
|
||||||
|
maxTurn: number;
|
||||||
|
maxPushTurn: number;
|
||||||
|
commandList: {
|
||||||
|
category: string;
|
||||||
|
values: CommandItem[];
|
||||||
|
}[];
|
||||||
|
serverNow: string;
|
||||||
|
serverNick: string;
|
||||||
|
mapName: string;
|
||||||
|
unitSet: string;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
import addMinutes from "date-fns/esm/addMinutes";
|
import addMinutes from "date-fns/esm/addMinutes";
|
||||||
import { isString, range } from "lodash";
|
import { range, trim } from "lodash";
|
||||||
import { stringifyUrl } from "query-string";
|
import { stringifyUrl } from "query-string";
|
||||||
import { defineComponent, ref, watch } from "vue";
|
import { onMounted, ref, watch } from "vue";
|
||||||
import { formatTime } from "@util/formatTime";
|
import { formatTime } from "@util/formatTime";
|
||||||
import { joinYearMonth } from "@util/joinYearMonth";
|
import { joinYearMonth } from "@util/joinYearMonth";
|
||||||
import { mb_strwidth } from "@util/mb_strwidth";
|
import { mb_strwidth } from "@util/mb_strwidth";
|
||||||
import { parseTime } from "@util/parseTime";
|
import { parseTime } from "@util/parseTime";
|
||||||
import { parseYearMonth } from "@util/parseYearMonth";
|
import { parseYearMonth } from "@util/parseYearMonth";
|
||||||
import { convertSearch초성 } from "./util/convertSearch초성";
|
|
||||||
import DragSelect from "@/components/DragSelect.vue";
|
import DragSelect from "@/components/DragSelect.vue";
|
||||||
import { SammoAPI } from "./SammoAPI";
|
import { SammoAPI } from "./SammoAPI";
|
||||||
|
import type { CommandItem } from "@/defs";
|
||||||
|
import CommandSelectForm from "@/components/CommandSelectForm.vue";
|
||||||
|
import { BButton, BButtonGroup, BDropdownItem, BDropdown, BDropdownText, BDropdownDivider } from "bootstrap-vue-3";
|
||||||
|
import { StoredActionsHelper } from "./util/StoredActionsHelper";
|
||||||
|
import type { TurnObj } from "@/defs";
|
||||||
|
import type { Args } from "./processing/args";
|
||||||
|
import { QueryActionHelper } from "./util/QueryActionHelper";
|
||||||
|
import SimpleClock from "./components/SimpleClock.vue";
|
||||||
|
import type { ReservedCommandResponse } from "./defs/API/Command";
|
||||||
|
|
||||||
type commandItem = {
|
const { maxTurn, maxPushTurn, commandList } = staticValues;
|
||||||
value: string;
|
|
||||||
title: string;
|
|
||||||
compensation: number;
|
|
||||||
simpleName: string;
|
|
||||||
possible: boolean;
|
|
||||||
reqArg: boolean;
|
|
||||||
searchText?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
declare const maxTurn: number;
|
|
||||||
declare const maxPushTurn: number;
|
|
||||||
declare const commandList: {
|
|
||||||
category: string;
|
|
||||||
values: commandItem[];
|
|
||||||
}[];
|
|
||||||
declare const serverNow: string;
|
|
||||||
type TurnObj = {
|
|
||||||
action: string;
|
|
||||||
brief: string;
|
|
||||||
arg: null | [] | Record<string, number | string | number[] | string[]>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type TurnObjWithTime = TurnObj & {
|
|
||||||
time: string;
|
|
||||||
year?: number;
|
|
||||||
month?: number;
|
|
||||||
tooltip?: string;
|
|
||||||
style?: Record<string, unknown>;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ReservedCommandResponse = {
|
|
||||||
result: true;
|
|
||||||
turnTime: string;
|
|
||||||
turnTerm: number;
|
|
||||||
year: number;
|
|
||||||
month: number;
|
|
||||||
date: string;
|
|
||||||
turn: TurnObj[];
|
|
||||||
autorun_limit: null | number;
|
|
||||||
};
|
|
||||||
|
|
||||||
const listReqArgCommand = new Set<string>();
|
const listReqArgCommand = new Set<string>();
|
||||||
|
const selectedCommand = ref(staticValues.commandList[0].values[0]);
|
||||||
|
const commandSelectForm = ref<InstanceType<typeof CommandSelectForm> | null>(null);
|
||||||
|
|
||||||
for (const commandCategories of commandList) {
|
for (const commandCategories of commandList) {
|
||||||
if (!commandCategories.values) {
|
if (!commandCategories.values) {
|
||||||
continue;
|
continue;
|
||||||
@@ -319,6 +316,16 @@ for (const commandCategories of commandList) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleForm($event: Event): void {
|
||||||
|
$event.preventDefault();
|
||||||
|
|
||||||
|
const form = commandSelectForm.value;
|
||||||
|
if (!form) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
form.toggle();
|
||||||
|
}
|
||||||
|
|
||||||
function isDropdownChildren(e?: Event): boolean {
|
function isDropdownChildren(e?: Event): boolean {
|
||||||
if (!e) {
|
if (!e) {
|
||||||
return false;
|
return false;
|
||||||
@@ -336,306 +343,448 @@ function isDropdownChildren(e?: Event): boolean {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchModeKey = `sammo_searchModeOn`;
|
const queryActionHelper = new QueryActionHelper(staticValues.maxTurn);
|
||||||
|
const storedActionsHelper = new StoredActionsHelper(
|
||||||
|
staticValues.serverNick,
|
||||||
|
"general",
|
||||||
|
staticValues.mapName,
|
||||||
|
staticValues.unitSet
|
||||||
|
);
|
||||||
|
|
||||||
export default defineComponent({
|
const reservedCommandList = queryActionHelper.reservedCommandList;
|
||||||
name: "PartialReservedCommand",
|
const prevSelectedTurnList = queryActionHelper.prevSelectedTurnList;
|
||||||
components: {
|
const selectedTurnList = queryActionHelper.selectedTurnList;
|
||||||
DragSelect,
|
|
||||||
},
|
const isEditMode = storedActionsHelper.isEditMode;
|
||||||
methods: {
|
|
||||||
updateNow() {
|
const flippedMaxTurn = 14;
|
||||||
const serverNow = addMilliseconds(new Date(), this.timeDiff);
|
|
||||||
this.serverNow = formatTime(serverNow, "HH:mm:ss");
|
const editModeRowHeight = 29.35;
|
||||||
setTimeout(() => {
|
const basicModeRowHeight = 34.4;
|
||||||
this.updateNow();
|
const viewMaxTurn = ref(flippedMaxTurn);
|
||||||
}, 1000 - serverNow.getMilliseconds());
|
const rowGridStyle = ref({
|
||||||
},
|
display: "grid",
|
||||||
toggleTurn(...turnList: number[] | string[]) {
|
gridTemplateRows: `repeat(${viewMaxTurn.value}, ${isEditMode.value ? editModeRowHeight : basicModeRowHeight}px)`,
|
||||||
for (let turnIdx of turnList) {
|
});
|
||||||
if (isString(turnIdx)) {
|
|
||||||
turnIdx = parseInt(turnIdx);
|
watch([isEditMode, viewMaxTurn], ([isEditMode, maxTurn]) => {
|
||||||
}
|
rowGridStyle.value.gridTemplateRows = `repeat(${maxTurn}, ${isEditMode ? editModeRowHeight : basicModeRowHeight}px)`;
|
||||||
if (this.turnList.has(turnIdx)) {
|
});
|
||||||
this.turnList.delete(turnIdx);
|
|
||||||
} else {
|
const isDragSingle = ref(false);
|
||||||
this.turnList.add(turnIdx);
|
const isDragToggle = ref(false);
|
||||||
}
|
|
||||||
}
|
const invCommandMap: Record<string, CommandItem> = {};
|
||||||
},
|
for (const category of commandList) {
|
||||||
selectTurn(...turnList: number[] | string[]) {
|
for (const command of category.values) {
|
||||||
this.turnList.clear();
|
invCommandMap[command.value] = command;
|
||||||
for (const turnIdx of turnList) {
|
}
|
||||||
if (isString(turnIdx)) {
|
}
|
||||||
this.turnList.add(parseInt(turnIdx));
|
|
||||||
} else {
|
function toggleViewMaxTurn() {
|
||||||
this.turnList.add(turnIdx);
|
if (viewMaxTurn.value == flippedMaxTurn) {
|
||||||
}
|
viewMaxTurn.value = maxTurn;
|
||||||
}
|
} else {
|
||||||
},
|
viewMaxTurn.value = flippedMaxTurn;
|
||||||
selectAll(e: Event | true) {
|
}
|
||||||
//NOTE: split 구현에 버그가 있어서, 수동으로 구분해야함
|
}
|
||||||
if (e !== true && isDropdownChildren(e)) {
|
|
||||||
return;
|
async function repeatGeneralCommand(amount: number) {
|
||||||
|
try {
|
||||||
|
await SammoAPI.Command.RepeatCommand({ amount });
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
alert(`실패했습니다: ${e}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await reloadCommandList();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function pushGeneralCommand(amount: number) {
|
||||||
|
try {
|
||||||
|
await SammoAPI.Command.PushCommand({ amount });
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
alert(`실패했습니다: ${e}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await reloadCommandList();
|
||||||
|
}
|
||||||
|
|
||||||
|
const serverNow = ref(new Date());
|
||||||
|
|
||||||
|
function pushGeneralCommandSingle(e: Event) {
|
||||||
|
//NOTE: split 구현에 버그가 있어서, 수동으로 구분해야함
|
||||||
|
if (isDropdownChildren(e)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isEditMode.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void pushGeneralCommand(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function pullGeneralCommandSingle(e: Event) {
|
||||||
|
//NOTE: split 구현에 버그가 있어서, 수동으로 구분해야함
|
||||||
|
if (isDropdownChildren(e)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isEditMode.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void pushGeneralCommand(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function reloadCommandList() {
|
||||||
|
let result: ReservedCommandResponse;
|
||||||
|
try {
|
||||||
|
result = await SammoAPI.Command.GetReservedCommand();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
alert(`실패했습니다: ${e}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let yearMonth = joinYearMonth(result.year, result.month);
|
||||||
|
|
||||||
|
const turnTime = parseTime(result.turnTime);
|
||||||
|
let nextTurnTime = new Date(turnTime);
|
||||||
|
|
||||||
|
const autorunLimitYearMonth = result.autorun_limit ?? yearMonth - 1;
|
||||||
|
const [autorunLimitYear, autorunLimitMonth] = parseYearMonth(autorunLimitYearMonth);
|
||||||
|
|
||||||
|
reservedCommandList.value = [];
|
||||||
|
for (const obj of result.turn) {
|
||||||
|
const [year, month] = parseYearMonth(yearMonth);
|
||||||
|
let tooltip: string[] = [];
|
||||||
|
let style: Record<string, unknown> = {};
|
||||||
|
|
||||||
|
const brief = obj.brief;
|
||||||
|
|
||||||
|
if (yearMonth <= autorunLimitYearMonth) {
|
||||||
|
if (obj.brief == "휴식") {
|
||||||
|
obj.brief = "휴식<small>(자율 행동)</small>";
|
||||||
}
|
}
|
||||||
|
style.color = "#aaffff";
|
||||||
|
|
||||||
if (this.turnList.size * 3 > this.maxTurn) {
|
tooltip.push(`자율 행동 기간: ${autorunLimitYear}년 ${autorunLimitMonth}월까지`);
|
||||||
this.turnList.clear();
|
|
||||||
} else {
|
|
||||||
for (let i = 0; i < this.maxTurn; i++) {
|
|
||||||
this.turnList.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
selectStep(begin: number, step: number) {
|
|
||||||
this.turnList.clear();
|
|
||||||
for (const idx of range(0, maxTurn)) {
|
|
||||||
if ((idx - begin) % step == 0) {
|
|
||||||
this.turnList.add(idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
toggleViewMaxTurn() {
|
|
||||||
if (this.viewMaxTurn == this.flippedMaxTurn) {
|
|
||||||
this.viewMaxTurn = this.maxTurn;
|
|
||||||
} else {
|
|
||||||
this.viewMaxTurn = this.flippedMaxTurn;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async repeatGeneralCommand(amount: number) {
|
|
||||||
try {
|
|
||||||
await SammoAPI.Command.RepeatCommand({ amount });
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
alert(`실패했습니다: ${e}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await this.reloadCommandList();
|
|
||||||
},
|
|
||||||
async pushGeneralCommand(amount: number) {
|
|
||||||
try {
|
|
||||||
await SammoAPI.Command.PushCommand({ amount });
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
alert(`실패했습니다: ${e}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await this.reloadCommandList();
|
|
||||||
},
|
|
||||||
pushGeneralCommandSingle(e: Event) {
|
|
||||||
//NOTE: split 구현에 버그가 있어서, 수동으로 구분해야함
|
|
||||||
if (isDropdownChildren(e)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void this.pushGeneralCommand(1);
|
|
||||||
},
|
|
||||||
pullGeneralCommandSingle(e: Event) {
|
|
||||||
//NOTE: split 구현에 버그가 있어서, 수동으로 구분해야함
|
|
||||||
if (isDropdownChildren(e)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
void this.pushGeneralCommand(-1);
|
|
||||||
},
|
|
||||||
async reloadCommandList() {
|
|
||||||
let result: ReservedCommandResponse;
|
|
||||||
try {
|
|
||||||
result = await SammoAPI.Command.GetReservedCommand();
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
alert(`실패했습니다: ${e}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const reservedCommandList: TurnObjWithTime[] = [];
|
|
||||||
let yearMonth = joinYearMonth(result.year, result.month);
|
|
||||||
|
|
||||||
const turnTime = parseTime(result.turnTime);
|
|
||||||
let nextTurnTime = new Date(turnTime);
|
|
||||||
|
|
||||||
const autorunLimitYearMonth = result.autorun_limit ?? yearMonth - 1;
|
|
||||||
const [autorunLimitYear, autorunLimitMonth] = parseYearMonth(
|
|
||||||
autorunLimitYearMonth
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const obj of result.turn) {
|
|
||||||
const [year, month] = parseYearMonth(yearMonth);
|
|
||||||
let tooltip: string[] = [];
|
|
||||||
let style: Record<string, unknown> = {};
|
|
||||||
|
|
||||||
const brief = obj.brief;
|
|
||||||
|
|
||||||
if (yearMonth <= autorunLimitYearMonth) {
|
|
||||||
if (obj.brief == "휴식") {
|
|
||||||
obj.brief = "휴식<small>(자율 행동)</small>";
|
|
||||||
}
|
|
||||||
style.color = "#aaffff";
|
|
||||||
|
|
||||||
tooltip.push(
|
|
||||||
`자율 행동 기간: ${autorunLimitYear}년 ${autorunLimitMonth}월까지`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mb_strwidth(brief) > 22) {
|
|
||||||
tooltip.push(brief);
|
|
||||||
}
|
|
||||||
|
|
||||||
reservedCommandList.push({
|
|
||||||
...obj,
|
|
||||||
year,
|
|
||||||
month,
|
|
||||||
time: formatTime(nextTurnTime, "HH:mm"),
|
|
||||||
tooltip: tooltip.length == 0 ? undefined : tooltip.join("\n"),
|
|
||||||
style,
|
|
||||||
});
|
|
||||||
|
|
||||||
yearMonth += 1;
|
|
||||||
nextTurnTime = addMinutes(nextTurnTime, result.turnTerm);
|
|
||||||
}
|
|
||||||
this.reservedCommandList = reservedCommandList;
|
|
||||||
|
|
||||||
const serverNowObj = parseTime(result.date);
|
|
||||||
const clientNowObj = new Date();
|
|
||||||
const timeDiff = serverNowObj.getTime() - clientNowObj.getTime();
|
|
||||||
this.timeDiff = timeDiff;
|
|
||||||
},
|
|
||||||
async reserveCommand() {
|
|
||||||
let turnList: number[];
|
|
||||||
if (this.turnList.size == 0) {
|
|
||||||
turnList = Array.from(this.prevTurnList.values());
|
|
||||||
} else {
|
|
||||||
turnList = Array.from(this.turnList.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (turnList.length == 0) {
|
|
||||||
turnList.push(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const commandName = this.selectedCommand.value;
|
|
||||||
|
|
||||||
if (listReqArgCommand.has(commandName)) {
|
|
||||||
document.location.href = stringifyUrl({
|
|
||||||
url: "v_processing.php",
|
|
||||||
query: {
|
|
||||||
command: commandName,
|
|
||||||
turnList: turnList.join("_"),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await SammoAPI.Command.ReserveCommand({
|
|
||||||
turnList,
|
|
||||||
action: commandName,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (this.turnList.size > 0) {
|
|
||||||
this.prevTurnList.clear();
|
|
||||||
for (const v of this.turnList) {
|
|
||||||
this.prevTurnList.add(v);
|
|
||||||
}
|
|
||||||
this.turnList.clear();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
alert(`실패했습니다: ${e}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await this.reloadCommandList();
|
|
||||||
},
|
|
||||||
toggleSearchCommand() {
|
|
||||||
const searchModeOn = !this.searchModeOn;
|
|
||||||
this.searchModeOn = searchModeOn;
|
|
||||||
localStorage.setItem(searchModeKey, searchModeOn ? "1" : "0");
|
|
||||||
},
|
|
||||||
chooseCommand(val: string){
|
|
||||||
this.selectedCommand = this.invCommandMap[val];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
const serverNowObj = parseTime(serverNow);
|
|
||||||
const clientNowObj = new Date();
|
|
||||||
const timeDiff = serverNowObj.getTime() - clientNowObj.getTime();
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
this.updateNow();
|
|
||||||
}, 1000 - serverNowObj.getMilliseconds());
|
|
||||||
|
|
||||||
const selectedCommand = commandList[0].values[0];
|
|
||||||
for (const subCategory of commandList) {
|
|
||||||
for (const command of subCategory.values) {
|
|
||||||
if (command.searchText) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
command.searchText = convertSearch초성(command.simpleName).join("|");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchModeOn = (localStorage.getItem(searchModeKey) ?? "0") != "0";
|
if (mb_strwidth(brief) > 22) {
|
||||||
|
tooltip.push(brief);
|
||||||
|
}
|
||||||
|
|
||||||
const emptyTurn: TurnObjWithTime[] = Array.from<TurnObjWithTime>({
|
reservedCommandList.value.push({
|
||||||
length: maxTurn,
|
...obj,
|
||||||
}).fill({
|
year,
|
||||||
arg: null,
|
month,
|
||||||
brief: "",
|
time: formatTime(nextTurnTime, "HH:mm"),
|
||||||
action: "",
|
tooltip: tooltip.length == 0 ? undefined : tooltip.join("\n"),
|
||||||
year: undefined,
|
style,
|
||||||
month: undefined,
|
|
||||||
time: "",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const prevTurnList = new Set([0]);
|
yearMonth += 1;
|
||||||
const turnList = new Set<number>();
|
nextTurnTime = addMinutes(nextTurnTime, result.turnTerm);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
serverNow.value = parseTime(result.date);
|
||||||
maxTurn,
|
}
|
||||||
|
|
||||||
maxPushTurn,
|
async function reserveCommandDirect(args: [number[], TurnObj][], reload = true): Promise<boolean> {
|
||||||
commandList,
|
const query: {
|
||||||
serverNow: formatTime(serverNowObj, "HH:mm:ss"),
|
turnList: number[];
|
||||||
timeDiff,
|
action: string;
|
||||||
prevTurnList,
|
arg: Args;
|
||||||
|
}[] = [];
|
||||||
|
for (const [turnList, { action, arg }] of args) {
|
||||||
|
query.push({
|
||||||
turnList,
|
turnList,
|
||||||
selectedCommand,
|
action,
|
||||||
reservedCommandList: emptyTurn,
|
arg,
|
||||||
autorun_limit: null as null | number,
|
});
|
||||||
searchModeOn,
|
}
|
||||||
};
|
|
||||||
},
|
try {
|
||||||
setup() {
|
await SammoAPI.Command.ReserveBulkCommand(query);
|
||||||
const flippedMaxTurn = 15;
|
queryActionHelper.releaseSelectedTurnList();
|
||||||
const viewMaxTurn = ref(flippedMaxTurn);
|
} catch (e) {
|
||||||
const rowGridStyle = ref({
|
console.error(e);
|
||||||
display: "grid",
|
alert(`실패했습니다: ${e}`);
|
||||||
gridTemplateRows: `repeat(${viewMaxTurn.value}, 29.4px)`,
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reload) {
|
||||||
|
await reloadCommandList();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function reserveCommand() {
|
||||||
|
let reqTurnList: number[] = queryActionHelper.getSelectedTurnList();
|
||||||
|
|
||||||
|
const commandName = selectedCommand.value.value;
|
||||||
|
|
||||||
|
if (listReqArgCommand.has(commandName)) {
|
||||||
|
document.location.href = stringifyUrl({
|
||||||
|
url: "v_processing.php",
|
||||||
|
query: {
|
||||||
|
command: commandName,
|
||||||
|
turnList: reqTurnList.join("_"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await SammoAPI.Command.ReserveCommand({
|
||||||
|
turnList: reqTurnList,
|
||||||
|
action: commandName,
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(viewMaxTurn, (val) => {
|
storedActionsHelper.pushRecentActions({
|
||||||
rowGridStyle.value.gridTemplateRows = `repeat(${val}, 29.4px)`;
|
action: commandName,
|
||||||
|
brief: result.brief,
|
||||||
|
arg: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const isDragSingle = ref(false);
|
queryActionHelper.releaseSelectedTurnList();
|
||||||
const isDragToggle = ref(false);
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
alert(`실패했습니다: ${e}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await reloadCommandList();
|
||||||
|
}
|
||||||
|
|
||||||
const invCommandMap: Record<string, commandItem> = {};
|
function chooseCommand(val?: string) {
|
||||||
for(const category of commandList){
|
if (!val) {
|
||||||
for(const command of category.values){
|
return;
|
||||||
invCommandMap[command.value] = command;
|
}
|
||||||
}
|
selectedCommand.value = invCommandMap[val];
|
||||||
|
void reserveCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
const commandQuickReserveForm = ref<InstanceType<typeof CommandSelectForm> | null>(null);
|
||||||
|
|
||||||
|
const currentQuickReserveTarget = ref(-1);
|
||||||
|
function chooseQuickReserveCommand(val?: string) {
|
||||||
|
if (!val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selectedCommand.value = invCommandMap[val];
|
||||||
|
selectedTurnList.value.clear();
|
||||||
|
selectedTurnList.value.add(currentQuickReserveTarget.value);
|
||||||
|
void reserveCommand();
|
||||||
|
}
|
||||||
|
function toggleQuickReserveForm(turnIdx: number) {
|
||||||
|
if (turnIdx == currentQuickReserveTarget.value) {
|
||||||
|
commandQuickReserveForm.value?.toggle();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currentQuickReserveTarget.value = turnIdx;
|
||||||
|
commandQuickReserveForm.value?.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(isEditMode, (newEditMode) => {
|
||||||
|
if (newEditMode) {
|
||||||
|
commandQuickReserveForm.value?.close();
|
||||||
|
currentQuickReserveTarget.value = -1;
|
||||||
|
} else {
|
||||||
|
commandSelectForm.value?.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const emptyTurnObj: TurnObj = { action: "휴식", brief: "휴식", arg: {} };
|
||||||
|
|
||||||
|
const recentActions = storedActionsHelper.recentActions;
|
||||||
|
const storedActions = storedActionsHelper.storedActions;
|
||||||
|
const activatedCategory = storedActionsHelper.activatedCategory;
|
||||||
|
|
||||||
|
async function eraseSelectedTurnList(releaseSelect = true): Promise<boolean> {
|
||||||
|
const result = await reserveCommandDirect([[queryActionHelper.getSelectedTurnList(), emptyTurnObj]]);
|
||||||
|
if (releaseSelect) {
|
||||||
|
queryActionHelper.releaseSelectedTurnList();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const clipboard = storedActionsHelper.clipboard;
|
||||||
|
|
||||||
|
async function clipboardCut(releaseSelect = true) {
|
||||||
|
clipboardCopy(false);
|
||||||
|
return eraseSelectedTurnList(releaseSelect);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clipboardCopy(releaseSelect = true) {
|
||||||
|
clipboard.value = queryActionHelper.extractQueryActions();
|
||||||
|
if (releaseSelect) {
|
||||||
|
queryActionHelper.releaseSelectedTurnList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function clipboardPaste(releaseSelect = true) {
|
||||||
|
const rawActions = clipboard.value;
|
||||||
|
if (rawActions === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = queryActionHelper.amplifyQueryActions(rawActions, queryActionHelper.getSelectedTurnList());
|
||||||
|
if (actions.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await reserveCommandDirect(actions);
|
||||||
|
if (releaseSelect) {
|
||||||
|
queryActionHelper.releaseSelectedTurnList();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function subRepeatCommand(releaseSelect = true): Promise<boolean> {
|
||||||
|
const reqTurnList = queryActionHelper.getSelectedTurnList();
|
||||||
|
const selectedMinTurnIdx = reqTurnList[0];
|
||||||
|
const selectedMaxTurnIdx = reqTurnList[reqTurnList.length - 1];
|
||||||
|
const queryLength = selectedMaxTurnIdx - selectedMinTurnIdx + 1;
|
||||||
|
|
||||||
|
const rawActions = queryActionHelper.extractQueryActions();
|
||||||
|
const actions = queryActionHelper.amplifyQueryActions(rawActions, range(selectedMinTurnIdx, maxTurn, queryLength));
|
||||||
|
|
||||||
|
const result = await reserveCommandDirect(actions);
|
||||||
|
if (releaseSelect) {
|
||||||
|
queryActionHelper.releaseSelectedTurnList();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function eraseAndPullCommand(releaseSelect = true): Promise<boolean> {
|
||||||
|
const reqTurnList = queryActionHelper.getSelectedTurnList();
|
||||||
|
const selectedMinTurnIdx = reqTurnList[0];
|
||||||
|
const selectedMaxTurnIdx = reqTurnList[reqTurnList.length - 1];
|
||||||
|
const queryLength = selectedMaxTurnIdx - selectedMinTurnIdx + 1;
|
||||||
|
|
||||||
|
if (selectedMinTurnIdx === 0) {
|
||||||
|
await pushGeneralCommand(-queryLength);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedMinTurnIdx + queryLength == maxTurn) {
|
||||||
|
return eraseSelectedTurnList(releaseSelect);
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions: [number[], TurnObj][] = [];
|
||||||
|
|
||||||
|
const emptyTurnList: number[] = [];
|
||||||
|
|
||||||
|
for (const srcTurnIdx of range(selectedMinTurnIdx + queryLength, maxTurn)) {
|
||||||
|
const rawAction = reservedCommandList.value[srcTurnIdx];
|
||||||
|
if (rawAction.action == emptyTurnObj.action) {
|
||||||
|
emptyTurnList.push(srcTurnIdx - queryLength);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
actions.push([
|
||||||
|
[srcTurnIdx - queryLength],
|
||||||
|
{
|
||||||
|
action: rawAction.action,
|
||||||
|
arg: rawAction.arg,
|
||||||
|
brief: rawAction.brief,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
emptyTurnList.push(...range(maxTurn - queryLength, maxTurn));
|
||||||
isDragSingle,
|
actions.push([emptyTurnList, emptyTurnObj]);
|
||||||
isDragToggle,
|
|
||||||
flippedMaxTurn,
|
const result = await reserveCommandDirect(actions);
|
||||||
viewMaxTurn,
|
if (releaseSelect) {
|
||||||
rowGridStyle,
|
queryActionHelper.releaseSelectedTurnList();
|
||||||
invCommandMap,
|
}
|
||||||
};
|
return result;
|
||||||
},
|
}
|
||||||
mounted() {
|
|
||||||
void this.reloadCommandList();
|
async function pushEmptyCommand(releaseSelect = true): Promise<boolean> {
|
||||||
},
|
const reqTurnList = queryActionHelper.getSelectedTurnList();
|
||||||
|
const selectedMinTurnIdx = reqTurnList[0];
|
||||||
|
const selectedMaxTurnIdx = reqTurnList[reqTurnList.length - 1];
|
||||||
|
const queryLength = selectedMaxTurnIdx - selectedMinTurnIdx + 1;
|
||||||
|
|
||||||
|
if (selectedMinTurnIdx === 0) {
|
||||||
|
await pushGeneralCommand(queryLength);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedMaxTurnIdx == maxTurn) {
|
||||||
|
return eraseSelectedTurnList(releaseSelect);
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions: [number[], TurnObj][] = [];
|
||||||
|
|
||||||
|
const emptyTurnList: number[] = [];
|
||||||
|
|
||||||
|
for (const srcTurnIdx of range(selectedMinTurnIdx, maxTurn - queryLength)) {
|
||||||
|
const rawAction = reservedCommandList.value[srcTurnIdx];
|
||||||
|
if (rawAction.action == emptyTurnObj.action) {
|
||||||
|
emptyTurnList.push(srcTurnIdx + queryLength);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
actions.push([
|
||||||
|
[srcTurnIdx + queryLength],
|
||||||
|
{
|
||||||
|
action: rawAction.action,
|
||||||
|
arg: rawAction.arg,
|
||||||
|
brief: rawAction.brief,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
emptyTurnList.push(...range(selectedMinTurnIdx, selectedMinTurnIdx + queryLength));
|
||||||
|
actions.push([emptyTurnList, emptyTurnObj]);
|
||||||
|
|
||||||
|
const result = await reserveCommandDirect(actions);
|
||||||
|
if (releaseSelect) {
|
||||||
|
queryActionHelper.releaseSelectedTurnList();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setStoredActions() {
|
||||||
|
const actions = queryActionHelper.extractQueryActions();
|
||||||
|
const turnBrief = new Map<number, string>();
|
||||||
|
for (const [subTurnList, action] of actions) {
|
||||||
|
const actionName = action.action.split("_");
|
||||||
|
const actionShortName = actionName.length == 1 ? actionName[0] : actionName[1];
|
||||||
|
for (const turnIdx of subTurnList) {
|
||||||
|
turnBrief.set(turnIdx, actionShortName[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const turnBriefStr = Array.from(turnBrief.entries())
|
||||||
|
.sort(([turnA], [turnB]) => turnA - turnB)
|
||||||
|
.map(([, action]) => action)
|
||||||
|
.join("");
|
||||||
|
|
||||||
|
const nickName = trim(prompt("선택한 턴들의 별명을 지어주세요", turnBriefStr) ?? "");
|
||||||
|
if (nickName == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
storedActionsHelper.setStoredActions(nickName, actions);
|
||||||
|
queryActionHelper.releaseSelectedTurnList();
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteStoredActions(actionKey: string) {
|
||||||
|
storedActionsHelper.deleteStoredActions(actionKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function useStoredAction(rawActions: [number[], TurnObj][]) {
|
||||||
|
const reqTurnList = queryActionHelper.getSelectedTurnList();
|
||||||
|
const actions = queryActionHelper.amplifyQueryActions(rawActions, reqTurnList);
|
||||||
|
const result = await reserveCommandDirect(actions);
|
||||||
|
queryActionHelper.releaseSelectedTurnList();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
void reloadCommandList();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@@ -648,9 +797,19 @@ export default defineComponent({
|
|||||||
|
|
||||||
.commandPad {
|
.commandPad {
|
||||||
background-color: $gray-900;
|
background-color: $gray-900;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commandTable {
|
.commandTable {
|
||||||
|
width: 100%;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns:
|
||||||
|
minmax(20px, 0.8fr) minmax(75px, 2.4fr) minmax(40px, 0.9fr)
|
||||||
|
4.8fr minmax(28px, 0.8fr);
|
||||||
|
//30, 70, 37.65, 160
|
||||||
|
}
|
||||||
|
|
||||||
|
.commandTable.isEditMode {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(30px, 1fr) minmax(75px, 2.5fr) minmax(40px, 1fr) 5fr;
|
grid-template-columns: minmax(30px, 1fr) minmax(75px, 2.5fr) minmax(40px, 1fr) 5fr;
|
||||||
@@ -700,11 +859,16 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.month_pad:hover {
|
.isEditMode .month_pad:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.plain-center {
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plain-center,
|
||||||
.month_pad,
|
.month_pad,
|
||||||
.time_pad,
|
.time_pad,
|
||||||
.turn_pad {
|
.turn_pad {
|
||||||
@@ -728,4 +892,4 @@ export default defineComponent({
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
+112
-43
@@ -1,63 +1,132 @@
|
|||||||
import { InvalidResponse } from "./defs";
|
import type { Args } from "./processing/args";
|
||||||
import { APIPathGen } from "./util/APIPathGen";
|
import {
|
||||||
import { callSammoAPI, ValidResponse } from "./util/callSammoAPI";
|
callSammoAPI, extractHttpMethod, GET, PATCH, POST, PUT,
|
||||||
|
type APITail, type APICallT, type RawArgType, type ValidResponse, type InvalidResponse
|
||||||
|
} from "./util/callSammoAPI";
|
||||||
export type { ValidResponse, InvalidResponse };
|
export type { ValidResponse, InvalidResponse };
|
||||||
|
import { APIPathGen, NumVar } from "./util/APIPathGen.js";
|
||||||
async function done<ResultType extends ValidResponse>(args?: Record<string, unknown>): Promise<ResultType>;
|
import type { BettingDetailResponse, BettingListResponse } from "./defs/API/Betting";
|
||||||
async function done<ResultType extends ValidResponse>(args: Record<string, unknown> | undefined, returnError: false): Promise<ResultType>;
|
import type { ReserveBulkCommandResponse, ReserveCommandResponse, ReservedCommandResponse } from "./defs/API/Command";
|
||||||
async function done<ResultType extends ValidResponse, ErrorType extends InvalidResponse>(args: Record<string, unknown> | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
import type { ChiefResponse } from "./defs/API/NationCommand";
|
||||||
|
import type { inheritBuffType } from "./defs/API/InheritAction";
|
||||||
async function done<ResultType extends ValidResponse, ErrorType extends InvalidResponse>(args?: Record<string, unknown>, returnError = false): Promise<ResultType | ErrorType> {
|
import type { SetBlockWarResponse, GeneralListResponse as NationGeneralListResponse } from "./defs/API/Nation";
|
||||||
console.error(`Can't directly call. ${args}, ${returnError}. Use auto-generated path API.`);
|
import type { UploadImageResponse } from "./defs/API/Misc";
|
||||||
return callSammoAPI<ResultType, ErrorType>([], args, true);
|
import type { JoinArgs } from "./defs/API/General";
|
||||||
}
|
import type { GetConstResponse } from "./defs/API/Global";
|
||||||
|
import type { GeneralListResponse } from "./defs";
|
||||||
|
|
||||||
const apiRealPath = {
|
const apiRealPath = {
|
||||||
Betting:{
|
Betting: {
|
||||||
Bet: done,
|
Bet: PUT as APICallT<{
|
||||||
GetBettingDetail: done,
|
bettingID: number,
|
||||||
GetBettingList: done,
|
bettingType: number[],
|
||||||
|
amount: number,
|
||||||
|
}>,
|
||||||
|
GetBettingDetail: NumVar('betting_id',
|
||||||
|
GET as APICallT<undefined, BettingDetailResponse>
|
||||||
|
),
|
||||||
|
GetBettingList: GET as APICallT<undefined, BettingListResponse>,
|
||||||
},
|
},
|
||||||
Command: {
|
Command: {
|
||||||
GetReservedCommand: done,
|
GetReservedCommand: GET as APICallT<undefined, ReservedCommandResponse>,
|
||||||
PushCommand: done,
|
PushCommand: PUT as APICallT<{
|
||||||
RepeatCommand: done,
|
amount: number
|
||||||
ReserveCommand: done,
|
}>,
|
||||||
|
RepeatCommand: PUT as APICallT<{
|
||||||
|
amount: number
|
||||||
|
}>,
|
||||||
|
ReserveCommand: PUT as APICallT<{
|
||||||
|
turnList: number[],
|
||||||
|
action: string,
|
||||||
|
arg?: Args
|
||||||
|
}, ReserveCommandResponse>,
|
||||||
|
ReserveBulkCommand: PUT as APICallT<{
|
||||||
|
turnList: number[],
|
||||||
|
action: string,
|
||||||
|
arg?: Args
|
||||||
|
}[], ReserveBulkCommandResponse>,
|
||||||
},
|
},
|
||||||
General: {
|
General: {
|
||||||
Join: done,
|
Join: POST as APICallT<JoinArgs>,
|
||||||
|
},
|
||||||
|
Global: {
|
||||||
|
GeneralList: GET as APICallT<{
|
||||||
|
with_token?: boolean
|
||||||
|
}, GeneralListResponse>,
|
||||||
|
GetConst: GET as APICallT<undefined, GetConstResponse>,
|
||||||
},
|
},
|
||||||
InheritAction: {
|
InheritAction: {
|
||||||
BuyHiddenBuff: done,
|
BuyHiddenBuff: PUT as APICallT<{
|
||||||
BuyRandomUnique: done,
|
type: inheritBuffType,
|
||||||
BuySpecificUnique: done,
|
level: number
|
||||||
ResetSpecialWar: done,
|
}>,
|
||||||
ResetTurnTime: done,
|
BuyRandomUnique: PUT as APICallT<undefined>,
|
||||||
SetNextSpecialWar: done,
|
BuySpecificUnique: PUT as APICallT<{
|
||||||
|
item: string,
|
||||||
|
amount: number,
|
||||||
|
}>,
|
||||||
|
ResetSpecialWar: PUT as APICallT<undefined>,
|
||||||
|
ResetTurnTime: PUT as APICallT<undefined>,
|
||||||
|
SetNextSpecialWar: PUT as APICallT<{
|
||||||
|
type: string,
|
||||||
|
}>,
|
||||||
|
},
|
||||||
|
Misc: {
|
||||||
|
UploadImage: POST as APICallT<{
|
||||||
|
imageData: string,
|
||||||
|
}, UploadImageResponse>
|
||||||
},
|
},
|
||||||
Misc: { UploadImage: done },
|
|
||||||
NationCommand: {
|
NationCommand: {
|
||||||
GetReservedCommand: done,
|
GetReservedCommand: GET as APICallT<undefined, ChiefResponse>,
|
||||||
PushCommand: done,
|
PushCommand: PUT as APICallT<{
|
||||||
RepeatCommand: done,
|
amount: number
|
||||||
ReserveCommand: done,
|
}>,
|
||||||
|
RepeatCommand: PUT as APICallT<{
|
||||||
|
amount: number
|
||||||
|
}>,
|
||||||
|
ReserveCommand: PUT as APICallT<{
|
||||||
|
turnList: number[],
|
||||||
|
action: string,
|
||||||
|
arg?: Args
|
||||||
|
}, ReserveCommandResponse>,
|
||||||
|
ReserveBulkCommand: PUT as APICallT<{
|
||||||
|
turnList: number[],
|
||||||
|
action: string,
|
||||||
|
arg?: Args
|
||||||
|
}[], ReserveBulkCommandResponse>,
|
||||||
},
|
},
|
||||||
Nation: {
|
Nation: {
|
||||||
SetNotice: done,
|
GeneralList: GET as APICallT<undefined, NationGeneralListResponse>,
|
||||||
SetScoutMsg: done,
|
SetNotice: PUT as APICallT<{
|
||||||
SetBill: done,
|
msg: string,
|
||||||
SetRate: done,
|
}>,
|
||||||
SetSecretLimit: done,
|
SetScoutMsg: PUT as APICallT<{
|
||||||
SetBlockWar: done,
|
msg: string,
|
||||||
SetBlockScout: done,
|
}>,
|
||||||
|
SetBill: PATCH as APICallT<{
|
||||||
|
amount: number,
|
||||||
|
}>,
|
||||||
|
SetRate: PATCH as APICallT<{
|
||||||
|
amount: number,
|
||||||
|
}>,
|
||||||
|
SetSecretLimit: PATCH as APICallT<{
|
||||||
|
amount: number,
|
||||||
|
}>,
|
||||||
|
SetBlockWar: PATCH as APICallT<{
|
||||||
|
value: boolean,
|
||||||
|
}, SetBlockWarResponse>,
|
||||||
|
SetBlockScout: PATCH as APICallT<{
|
||||||
|
value: boolean,
|
||||||
|
}>,
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const SammoAPI = APIPathGen<typeof done, typeof apiRealPath>(apiRealPath, (path: string[]) => {
|
export const SammoAPI = APIPathGen(apiRealPath, (path: string[], tail: APITail, pathParam) => {
|
||||||
return (args?: Record<string, unknown>, returnError?: boolean) => {
|
const method = extractHttpMethod(tail);
|
||||||
|
return (args?: RawArgType, returnError?: boolean) => {
|
||||||
if (returnError) {
|
if (returnError) {
|
||||||
return callSammoAPI(path.join('/'), args, true);
|
return callSammoAPI(method, path.join('/'), args, pathParam, true);
|
||||||
}
|
}
|
||||||
return callSammoAPI(path.join('/'), args);
|
return callSammoAPI(method, path.join('/'), args, pathParam);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
+16
-18
@@ -1,30 +1,28 @@
|
|||||||
import { InvalidResponse } from "./defs";
|
import type { AutoLoginFailed, AutoLoginNonceResponse, AutoLoginResponse, LoginFailed, LoginResponse } from "./defs/API/Login";
|
||||||
import { APIPathGen } from "./util/APIPathGen";
|
import { APIPathGen } from "./util/APIPathGen";
|
||||||
import { callSammoAPI, ValidResponse } from "./util/callSammoAPI";
|
import { callSammoAPI, extractHttpMethod, GET, POST, type APICallT, type APITail, type InvalidResponse, type RawArgType, type ValidResponse } from "./util/callSammoAPI";
|
||||||
export type { ValidResponse, InvalidResponse };
|
export type { ValidResponse, InvalidResponse };
|
||||||
|
|
||||||
async function done<ResultType extends ValidResponse>(args?: Record<string, unknown>): Promise<ResultType>;
|
|
||||||
async function done<ResultType extends ValidResponse>(args: Record<string, unknown> | undefined, returnError: false): Promise<ResultType>;
|
|
||||||
async function done<ResultType extends ValidResponse, ErrorType extends InvalidResponse>(args: Record<string, unknown> | undefined, returnError: true): Promise<ResultType | ErrorType>;
|
|
||||||
|
|
||||||
async function done<ResultType extends ValidResponse, ErrorType extends InvalidResponse>(args?: Record<string, unknown>, returnError = false): Promise<ResultType | ErrorType>{
|
|
||||||
console.error(`Can't directly call. ${args}, ${returnError}. Use auto-generated path API.`);
|
|
||||||
return callSammoAPI<ResultType, ErrorType>([], args, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
const apiRealPath = {
|
const apiRealPath = {
|
||||||
Login: {
|
Login: {
|
||||||
LoginByID: done,
|
LoginByID: POST as APICallT<{
|
||||||
LoginByToken: done,
|
username: string,
|
||||||
ReqNonce: done,
|
password: string,
|
||||||
|
}, LoginResponse, LoginFailed>,
|
||||||
|
LoginByToken: POST as APICallT<{
|
||||||
|
hashedToken: string,
|
||||||
|
token_id: number,
|
||||||
|
}, AutoLoginResponse, AutoLoginFailed>,
|
||||||
|
ReqNonce: GET as APICallT<undefined, AutoLoginNonceResponse, AutoLoginFailed>
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const SammoRootAPI = APIPathGen<typeof done, typeof apiRealPath>(apiRealPath, (path: string[]) => {
|
export const SammoRootAPI = APIPathGen(apiRealPath, (path: string[], tail: APITail, pathParam) => {
|
||||||
return (args?: Record<string, unknown>, returnError?: boolean) => {
|
const method = extractHttpMethod(tail);
|
||||||
|
return (args?: RawArgType, returnError?: boolean) => {
|
||||||
if (returnError) {
|
if (returnError) {
|
||||||
return callSammoAPI(path.join('/'), args, true);
|
return callSammoAPI(method, path.join('/'), args, pathParam, true);
|
||||||
}
|
}
|
||||||
return callSammoAPI(path.join('/'), args);
|
return callSammoAPI(method, path.join('/'), args, pathParam);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user