feat,refac: 중원 정보 페이지

This commit is contained in:
2022-04-21 03:24:11 +09:00
parent 79b92427aa
commit 994daf11d3
10 changed files with 282 additions and 243 deletions
-1
View File
@@ -52,7 +52,6 @@ return [
'hwe/v_chiefCenter.php',
'hwe/b_currentCity.php',
'hwe/v_nationStratFinan.php',
'hwe/b_diplomacy.php',
'hwe/b_genList.php',
'hwe/b_myBossInfo.php',
'hwe/b_myCityInfo.php',
-236
View File
@@ -1,236 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("중원정보", 1);
$me = $db->queryFirstRow('SELECT no,nation FROM general WHERE owner=%i', $userID);
$myNationID = $me['nation'];
$nations = array_filter(getAllNationStaticInfo(), function (array $nation) {
return $nation['level'];
});
uasort($nations, function (array $lhs, array $rhs) {
return - ($lhs['power'] <=> $rhs['power']);
});
$nationCnt = count($nations);
foreach ($db->queryAllLists('SELECT nation, count(city) FROM city WHERE nation != 0 GROUP BY nation') as [$nationID, $cityCnt]) {
$nations[$nationID]['city_cnt'] = $cityCnt;
}
$realConflict = [];
foreach ($db->queryAllLists('SELECT city, `name`, conflict FROM city WHERE conflict!=%s', '{}') as [
$cityID,
$cityName,
$rawConflict
]) {
$rawConflict = Json::decode($rawConflict);
if (count($rawConflict) < 2) {
continue;
}
$sum = array_sum($rawConflict);
$conflict = [];
foreach ($rawConflict as $nationID => $killnum) {
$conflict[$nationID] = [
'killnum' => $killnum,
'percent' => round(100 * $killnum / $sum, 1),
'name' => $nations[$nationID]['name'],
'color' => $nations[$nationID]['color']
];
}
$realConflict[] = [$cityID, $cityName, $conflict];
};
$diplomacyList = [];
foreach ($db->queryAllLists('SELECT me, you, state FROM diplomacy') as [$me, $you, $state]) {
if (!key_exists($me, $diplomacyList)) {
$diplomacyList[$me] = [];
}
$diplomacyList[$me][$you] = $state;
}
$cellWidth = intdiv(888, max(1, $nationCnt));
$defaultStateChar = '?';
$sameNationStateChar = '';
$infomativeStateCharMap = [
0 => '<span style="color:red;">★</span>',
1 => '<span style="color:magenta;">▲</span>',
2 => 'ㆍ',
7 => '<span style="color:green;">@</span>'
];
$neutralStateCharMap = [
0 => '<span style="color:red;">★</span>',
1 => '<span style="color:magenta;">▲</span>'
];
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 중원 정보</title>
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printJS('d_shared/base_map.js') ?>
<?= 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" />
<?= WebUtil::printCSS('css/map.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']) ?>
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>중 원 정 보<br><?= backButton() ?></td>
</tr>
</table>
<br>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td colspan=<?= $nationCnt + 1 ?> align=center bgcolor=blue>외 교 현 황</td>
</tr>
<tr>
<td align=center width=130 style=background-color:<?= GameConst::$basecolor2 ?>;>&nbsp;</td>
<?php foreach ($nations as $nation) : ?>
<td align=center width=<?= $cellWidth ?> style='background-color:<?= $nation['color'] ?>;color:<?= newColor($nation['color']) ?>'><?= $nation['name'] ?></td>
<?php endforeach; ?>
</tr>
<?php foreach ($nations as $me => $meNation) : ?>
<tr style='text-align:center;'>
<td align=center style='background-color:<?= $meNation['color'] ?>;color:<?= newColor($meNation['color']) ?>'><?= $meNation['name'] ?></td>
<?php foreach (array_keys($nations) as $you) : ?>
<td <?= ($me == $myNationID || $you == $myNationID) ? 'style="background-color:' . GameConst::$basecolor3 . '"' : '' ?>><?php
if ($me == $you) {
echo $sameNationStateChar;
} else if ($me == $myNationID || $you == $myNationID || $session->userGrade >= 5) {
echo $infomativeStateCharMap[$diplomacyList[$me][$you]] ?? $defaultStateChar;
} else {
echo $neutralStateCharMap[$diplomacyList[$me][$you]] ?? $defaultStateChar;
}
?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
<tr>
<td colspan=<?= $nationCnt + 1 ?> align=center>불가침 : <font color=limegreen>@</font>, 통상 : ㆍ, 선포 : <font color=magenta>▲</font>, 교전 : <font color=red>★</font>
</td>
</tr>
</table>
<?php if ($realConflict) : ?>
<br>
<table align='center' width=1000 class='tb_layout bg0'>
<tr>
<td colspan=2 align=center bgcolor=magenta>분 쟁 현 황</td>
</tr>
<?php foreach ($realConflict as list($cityID, $cityName, $conflict)) : ?>
<tr>
<td align=center width=48><?= $cityName ?></td>
<td style='width:948px;position:relative;'>
<table class='tb_layout bg0' style='width:100%;'>
<?php foreach ($conflict as $item) : ?>
<tr>
<td width=130 align=right style='color:<?= newColor($item['color']) ?>;background-color:<?= $item['color'] ?>;'><?= $item['name'] ?>&nbsp;</td>
<td width=48 align=right><?= (float)$item['percent'] ?> %&nbsp;</td>
<td width=*>
<div style='display:inline-block;width:<?= $item['percent'] ?>%;background-color:<?= $item['color'] ?>;'>&nbsp;</div>
</td>
</tr>
<?php endforeach; ?>
</table>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td colspan=2 height=5 class='bg1'></td>
</tr>
</table>
<?php endif; ?>
<br>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td colspan=5 align=center bgcolor=green>
<font size=3>중 원 지 도</font>
</td>
</tr>
<tr>
<td width=698 height=420>
<?= getMapHtml() ?>
</td>
<td id='nation_list_frame'>
<table id='nation_list'>
<thead>
<tr>
<th width=130>국명</th>
<th width=70>국력</th>
<th width=45>장수</th>
<th width=45>속령</th>
</tr>
</thead>
<tbody>
<?php foreach ($nations as $nation) : ?>
<tr>
<td><span style='color:<?= newColor($nation['color']) ?>;background-color:<?= $nation['color'] ?>'><?= $nation['name'] ?></td>
<td style='text-align:right'><?= number_format($nation['power']) ?></td>
<td style='text-align:right'><?= number_format($nation['gennum']) ?></td>
<td style='text-align:right'><?= number_format($nation['city_cnt']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot></tfoot>
</table>
</td>
</tr>
</table>
<br>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td><?= backButton() ?></td>
</tr>
<tr>
<td><?= banner() ?></td>
</tr>
</table>
<script>
reloadWorldMap({
neutralView: true,
showMe: true,
useCachedMap: true
});
</script>
</body>
</html>
+1 -1
View File
@@ -99,7 +99,7 @@ class GetDiplomacy extends \sammo\BaseAPI
return [
'result' => true,
'nations' => $nations,
'nations' => array_values($nations),
'conflict' => $realConflict,
'diplomacyList' => $diplomacyList,
'myNationID' => $myNationID,
+2 -2
View File
@@ -14,8 +14,8 @@ class GetMap extends \sammo\BaseAPI
public function validateArgs(): ?string
{
$v = new Validator($this->args);
$v->rule('boolean', 'neutralView')
->rule('boolean', 'showMe');
$v->rule('in', 'neutralView', [0, 1])
->rule('in', 'showMe', [0, 1]);
if (!$v->validate()) {
return $v->errorStr();
}
+1 -1
View File
@@ -11,7 +11,7 @@
<?=$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='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='v_globalDiplomacy.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='v_inheritPoint.php' class='commandButton <?=$btnClass??""?>'>유산 관리</a><?=$btnEnd??''?>
+221
View File
@@ -0,0 +1,221 @@
<template>
<BContainer v-if="asyncReady" id="container" :toast="{ root: true }" class="pageGlobalDiplomacy">
<TopBackBar title="중원 정보"></TopBackBar>
<div class="diplomacy bg0">
<div class="s-border-tb center tb-title" style="background-color: blue">외교 현황</div>
<div class="diplomacy_area">
<table v-if="diplomacy" class="center" style="margin: auto; min-width: 400px">
<thead>
<tr>
<th></th>
<th
class="thead-nation"
v-for="nation of diplomacy.nations"
:key="nation.nation"
:style="{
color: isBrightColor(nation.color) ? '#000' : '#fff',
backgroundColor: nation.color,
}"
>
{{ nation.name }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="me of diplomacy.nations" :key="me.nation">
<th
class="tbody-nation"
:style="{
color: isBrightColor(me.color) ? '#000' : '#fff',
backgroundColor: me.color,
}"
>
{{ me.name }}
</th>
<template v-for="you of diplomacy.nations" :key="you.nation">
<td class="tbody-cell" v-if="me.nation == you.nation"></td>
<td
class="tbody-cell"
style="background-color: #660000"
v-else-if="me.nation == diplomacy.myNationID || you.nation == diplomacy.myNationID"
v-html="infomativeStateCharMap[diplomacy.diplomacyList[me.nation][you.nation]]"
/>
<td
class="tbody-cell"
v-else
v-html="neutralStateCharMap[diplomacy.diplomacyList[me.nation][you.nation]]"
/>
</template>
</tr>
</tbody>
<tfoot>
<tr>
<td :colspan="Object.keys(diplomacy.nations).length + 1" class="center">
불가침 :
<span style="color: limegreen">@</span>, 통상 : , 선포 : <span style="color: magenta"></span>, 교전 :
<span style="color: red"></span>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
<div class="map_area mx-0 bg0">
<div class="s-border-tb center tb-title" style="background-color: green">중원 지도</div>
<div class="row g-0">
<div class="map_position">
<MapViewer
v-if="map"
:server-nick="serverNick"
:serverID="serverID"
:map-name="unwrap(gameConstStore?.gameConst.mapName)"
:model-value="map"
:is-detail-map="true"
:city-position="cityPosition"
:format-city-info="formatCityInfoText"
:image-path="imagePath"
:disallow-click="true"
/>
</div>
<div class="nation_position"><SimpleNationList v-if="diplomacy" :nations="diplomacy.nations" /></div>
</div>
</div>
<BottomBar></BottomBar>
</BContainer>
</template>
<script lang="ts">
declare const staticValues: {
serverNick: string;
serverID: string;
};
declare const getCityPosition: () => CityPositionMap;
declare const formatCityInfo: (city: MapCityParsedRaw) => MapCityParsed;
</script>
<script lang="ts" setup>
import { onMounted, provide, ref } from "vue";
import { BContainer, useToast } from "bootstrap-vue-3";
import TopBackBar from "@/components/TopBackBar.vue";
import BottomBar from "@/components/BottomBar.vue";
import { SammoAPI } from "./SammoAPI";
import SimpleNationList from "./components/SimpleNationList.vue";
import MapViewer, { type CityPositionMap, type MapCityParsedRaw, type MapCityParsed } from "./components/MapViewer.vue";
import { getGameConstStore, type GameConstStore } from "./GameConstStore";
import { unwrap } from "@/util/unwrap";
import type { diplomacyState, MapResult } from "./defs";
import type { GetDiplomacyResponse } from "./defs/API/Global";
import { isString } from "lodash";
import { isBrightColor } from "@/util/isBrightColor";
const serverID = staticValues.serverID;
const serverNick = staticValues.serverNick;
const asyncReady = ref<boolean>(false);
const gameConstStore = ref<GameConstStore>();
provide("gameConstStore", gameConstStore);
const storeP = getGameConstStore().then((store) => {
gameConstStore.value = store;
});
void Promise.all([storeP]).then(() => {
asyncReady.value = true;
});
const infomativeStateCharMap: Record<diplomacyState, string> = {
0: '<span style="color:red;">★</span>',
1: '<span style="color:magenta;">▲</span>',
2: "ㆍ",
7: '<span style="color:green;">@</span>',
};
const neutralStateCharMap: Record<diplomacyState, string> = {
0: '<span style="color:red;">★</span>',
1: '<span style="color:magenta;">▲</span>',
2: "",
7: "에러",
};
const cityPosition = getCityPosition();
const formatCityInfoText = formatCityInfo;
const imagePath = window.pathConfig.gameImage;
const map = ref<MapResult>();
const diplomacy = ref<GetDiplomacyResponse>();
const toasts = unwrap(useToast());
onMounted(async () => {
try {
map.value = await SammoAPI.Global.GetMap({
neutralView: 0,
showMe: 1,
});
} catch (e) {
if (isString(e)) {
toasts.danger({
title: "에러",
body: e,
});
}
console.error(e);
}
});
onMounted(async () => {
try {
diplomacy.value = await SammoAPI.Global.GetDiplomacy();
} catch (e) {
if (isString(e)) {
toasts.danger({
title: "에러",
body: e,
});
}
console.error(e);
}
});
</script>
<style lang="scss" scoped>
.diplomacy_area {
width: 100%;
overflow-x: auto;
}
.thead-nation {
writing-mode: vertical-rl;
text-orientation: mixed;
text-align: end;
padding-bottom: 1ch;
padding-top: 1ch;
padding-left: 0;
padding-right: 0;
min-width: 1ch;
max-width: 3ch;
font-weight: normal;
}
.tbody-nation {
text-align: end;
padding-right: 1ch;
padding-left: 1ch;
min-width: 10ch;
font-weight: normal;
}
.diplomacy {
margin-top: 1.5em;
}
.map_area {
margin-top: 1.5em;
}
.tb-title {
font-size: 1.2em;
}
.tbody-cell {
border-left: solid 1px gray;
border-top: solid 1px gray;
padding: 0;
}
</style>
+4 -1
View File
@@ -58,7 +58,10 @@ const apiRealPath = {
NumVar('month', GET as APICallT<undefined, GetHistoryResponse>
))),
GetCurrentHistory: GET as APICallT<undefined, GetCurrentHistoryResponse>,
GetMap: GET as APICallT<undefined, MapResult>,
GetMap: GET as APICallT<{
neutralView?: 0 | 1,
showMe?: 0 | 1,
}, MapResult>,
GetCachedMap: GET as APICallT<undefined, CachedMapResult>,
GetDiplomacy: GET as APICallT<undefined, GetDiplomacyResponse>,
},
+2 -1
View File
@@ -32,6 +32,7 @@
"v_nationStratFinan": "v_nationStratFinan.ts",
"v_processing": "v_processing.ts",
"v_nationBetting": "v_nationBetting.ts",
"v_nationGeneral": "v_nationGeneral.ts"
"v_nationGeneral": "v_nationGeneral.ts",
"v_globalDiplomacy": "v_globalDiplomacy"
}
}
+16
View File
@@ -0,0 +1,16 @@
import "@scss/history.scss";
import { createApp } from 'vue'
import PageGlobalDiplomacy from '@/PageGlobalDiplomacy.vue';
import { BootstrapVue3, BToastPlugin } from 'bootstrap-vue-3'
import { setAxiosXMLHttpRequest } from '@util/setAxiosXMLHttpRequest';
import { auto500px } from "./util/auto500px";
import { htmlReady } from "./util/htmlReady";
import { insertCustomCSS } from "./util/customCSS";
setAxiosXMLHttpRequest();
auto500px();
htmlReady(() => {
insertCustomCSS();
});
createApp(PageGlobalDiplomacy).use(BootstrapVue3).use(BToastPlugin).mount('#app');
+35
View File
@@ -0,0 +1,35 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$mapName = GameConst::$mapName;
?>
<!DOCTYPE html>
<html>
<head>
<title><?= UniqueConst::$serverName ?>:중원정보</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=500" />
<?= WebUtil::printJS('../d_shared/common_path.js', true) ?>
<?= WebUtil::printJS("js/map/theme_{$mapName}.js") ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printStaticValues([
'staticValues' => [
'serverNick' => DB::prefix(),
'serverID' => UniqueConst::$serverID,
],
]) ?>
<?= WebUtil::printDist('vue', 'v_globalDiplomacy', true) ?>
</head>
<body>
<div id="app"></div>
</body>
</html>