feat(WIP): processing, 출병 추가

- 장수 선택기 추가
- v-model 안 쓰는 바보짓 수정
- proc 전역 변수를 procRes로 묶음
This commit is contained in:
2021-12-18 16:00:53 +09:00
parent 3ef5c2aa6d
commit 03993052a3
16 changed files with 407 additions and 88 deletions
+5 -3
View File
@@ -173,9 +173,11 @@ class che_강행 extends Command\GeneralCommand
public function exportJSVars(): array public function exportJSVars(): array
{ {
return [ return [
'cities' => \sammo\JSOptionsForCities(), 'mapTheme' => \sammo\getMapTheme(),
'mapTheme' => getMapTheme(), 'procRes' => [
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 3), 'cities' => \sammo\JSOptionsForCities(),
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 3),
],
]; ];
} }
} }
+5 -3
View File
@@ -181,9 +181,11 @@ class che_이동 extends Command\GeneralCommand
public function exportJSVars(): array public function exportJSVars(): array
{ {
return [ return [
'cities' => \sammo\JSOptionsForCities(), 'mapTheme' => \sammo\getMapTheme(),
'mapTheme' => getMapTheme(), 'procRes' => [
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 1), 'cities' => \sammo\JSOptionsForCities(),
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 1),
],
]; ];
} }
} }
+3 -1
View File
@@ -243,8 +243,10 @@ class che_출병 extends Command\GeneralCommand
public function exportJSVars(): array public function exportJSVars(): array
{ {
return [ return [
'cities' => \sammo\JSOptionsForCities(),
'mapTheme' => \sammo\getMapTheme(), 'mapTheme' => \sammo\getMapTheme(),
'procRes' => [
'cities' => \sammo\JSOptionsForCities(),
],
]; ];
} }
} }
+77 -46
View File
@@ -1,9 +1,13 @@
<?php <?php
namespace sammo\Command\Nation; namespace sammo\Command\Nation;
use \sammo\{ use \sammo\{
DB, Util, JosaUtil, DB,
General, DummyGeneral, Util,
JosaUtil,
General,
DummyGeneral,
ActionLogger, ActionLogger,
GameConst, GameConst,
LastTurn, LastTurn,
@@ -18,41 +22,44 @@ use function \sammo\cutTurn;
use \sammo\Constraint\Constraint; use \sammo\Constraint\Constraint;
use \sammo\Constraint\ConstraintHelper; use \sammo\Constraint\ConstraintHelper;
class che_발령 extends Command\NationCommand{ class che_발령 extends Command\NationCommand
{
static protected $actionName = '발령'; static protected $actionName = '발령';
static public $reqArg = true; static public $reqArg = true;
protected function argTest():bool{ protected function argTest(): bool
if($this->arg === null){ {
if ($this->arg === null) {
return false; return false;
} }
//NOTE: 사망 직전에 턴을 넣을 수 있으므로, 존재하지 않는 장수여도 argTest에서 바로 탈락시키지 않음 //NOTE: 사망 직전에 턴을 넣을 수 있으므로, 존재하지 않는 장수여도 argTest에서 바로 탈락시키지 않음
if(!key_exists('destGeneralID', $this->arg)){ if (!key_exists('destGeneralID', $this->arg)) {
return false; return false;
} }
if(!key_exists('destCityID', $this->arg)){ if (!key_exists('destCityID', $this->arg)) {
return false; return false;
} }
if(CityConst::byID($this->arg['destCityID']) === null){ if (CityConst::byID($this->arg['destCityID']) === null) {
return false; return false;
} }
$destGeneralID = $this->arg['destGeneralID']; $destGeneralID = $this->arg['destGeneralID'];
$destCityID = $this->arg['destCityID']; $destCityID = $this->arg['destCityID'];
$this->arg = [ $this->arg = [
'destGeneralID'=>$destGeneralID, 'destGeneralID' => $destGeneralID,
'destCityID'=>$destCityID, 'destCityID' => $destCityID,
]; ];
return true; return true;
} }
protected function init(){ protected function init()
{
$general = $this->generalObj; $general = $this->generalObj;
$this->setCity(); $this->setCity();
$this->setNation(); $this->setNation();
$this->minConditionConstraints=[ $this->minConditionConstraints = [
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -67,14 +74,14 @@ class che_발령 extends Command\NationCommand{
$destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, 1); $destGeneral = General::createGeneralObjFromDB($this->arg['destGeneralID'], null, 1);
$this->setDestGeneral($destGeneral); $this->setDestGeneral($destGeneral);
if($this->arg['destGeneralID'] == $this->getGeneral()->getID()){ if ($this->arg['destGeneralID'] == $this->getGeneral()->getID()) {
$this->fullConditionConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::AlwaysFail('본인입니다') ConstraintHelper::AlwaysFail('본인입니다')
]; ];
return; return;
} }
$this->fullConditionConstraints=[ $this->fullConditionConstraints = [
ConstraintHelper::BeChief(), ConstraintHelper::BeChief(),
ConstraintHelper::NotBeNeutral(), ConstraintHelper::NotBeNeutral(),
ConstraintHelper::OccupiedCity(), ConstraintHelper::OccupiedCity(),
@@ -86,29 +93,34 @@ class che_발령 extends Command\NationCommand{
]; ];
} }
public function getFailString():string{ public function getFailString(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$failReason = $this->testFullConditionMet(); $failReason = $this->testFullConditionMet();
if($failReason === null){ if ($failReason === null) {
throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집'); throw new \RuntimeException('실행 가능한 커맨드에 대해 실패 이유를 수집');
} }
$destGeneralName = $this->destGeneralObj->getName(); $destGeneralName = $this->destGeneralObj->getName();
return "{$failReason} <Y>{$destGeneralName}</> {$commandName} 실패."; return "{$failReason} <Y>{$destGeneralName}</> {$commandName} 실패.";
} }
public function getCost():array{ public function getCost(): array
{
return [0, 0]; return [0, 0];
} }
public function getPreReqTurn():int{ public function getPreReqTurn(): int
{
return 0; return 0;
} }
public function getPostReqTurn():int{ public function getPostReqTurn(): int
{
return 0; return 0;
} }
public function getBrief():string{ public function getBrief(): string
{
$commandName = $this->getName(); $commandName = $this->getName();
$destGeneralName = $this->destGeneralObj->getName(); $destGeneralName = $this->destGeneralObj->getName();
$destCityName = CityConst::byID($this->arg['destCityID'])->name; $destCityName = CityConst::byID($this->arg['destCityID'])->name;
@@ -117,8 +129,9 @@ class che_발령 extends Command\NationCommand{
} }
public function run():bool{ public function run(): bool
if(!$this->hasFullConditionMet()){ {
if (!$this->hasFullConditionMet()) {
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도'); throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
} }
@@ -144,8 +157,8 @@ class che_발령 extends Command\NationCommand{
$destGeneral->getLogger()->pushGeneralActionLog("<Y>{$generalName}</>에 의해 <G><b>{$destCityName}</b></>{$josaRo} 발령됐습니다. <1>$date</>"); $destGeneral->getLogger()->pushGeneralActionLog("<Y>{$generalName}</>에 의해 <G><b>{$destCityName}</b></>{$josaRo} 발령됐습니다. <1>$date</>");
$yearMonth = Util::joinYearMonth($this->env['year'], $this->env['month']); $yearMonth = Util::joinYearMonth($this->env['year'], $this->env['month']);
if(cutTurn($general->getTurnTime(), $this->env['turnterm']) != cutTurn($destGeneral->getTurnTime(), $this->env['turnterm'])){ if (cutTurn($general->getTurnTime(), $this->env['turnterm']) != cutTurn($destGeneral->getTurnTime(), $this->env['turnterm'])) {
$yearMonth+=1; $yearMonth += 1;
} }
$destGeneral->setAuxVar('last발령', $yearMonth); $destGeneral->setAuxVar('last발령', $yearMonth);
$logger->pushGeneralActionLog("<Y>{$destGeneralName}</>{$josaUl} <G><b>{$destCityName}</b></>{$josaRo} 발령했습니다. <1>$date</>"); $logger->pushGeneralActionLog("<Y>{$destGeneralName}</>{$josaUl} <G><b>{$destCityName}</b></>{$josaRo} 발령했습니다. <1>$date</>");
@@ -157,6 +170,24 @@ class che_발령 extends Command\NationCommand{
return true; return true;
} }
public function exportJSVars(): array
{
$db = DB::db();
$nationID = $this->getNationID();
$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);
return [
'mapTheme' => \sammo\getMapTheme(),
'procRes' => [
'distanceList' => \sammo\JSCitiesBasedOnDistance($this->generalObj->getCityID(), 1),
'cities' => \sammo\JSOptionsForCities(),
'troops' => $troops,
'generals' => $destRawGenerals,
'generalsKey' => ['no', 'name', 'officerLevel', 'npc', 'gold', 'rice', 'leadership', 'strength', 'intel', 'cityID', 'crew', 'train', 'atmos', 'troopID']
]
];
}
public function getJSPlugins(): array public function getJSPlugins(): array
{ {
return [ return [
@@ -171,16 +202,16 @@ class che_발령 extends Command\NationCommand{
$nationID = $this->generalObj->getNationID(); $nationID = $this->generalObj->getNationID();
$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->query('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->query('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);
$destGeneralList = []; $destGeneralList = [];
foreach($destRawGenerals as $destGeneral){ foreach ($destRawGenerals as $destGeneral) {
$nameColor = \sammo\getNameColor($destGeneral['npc']); $nameColor = \sammo\getNameColor($destGeneral['npc']);
if($nameColor){ if ($nameColor) {
$nameColor = " style='color:{$nameColor}'"; $nameColor = " style='color:{$nameColor}'";
} }
$name = $destGeneral['name']; $name = $destGeneral['name'];
if($destGeneral['officer_level'] >= 5){ if ($destGeneral['officer_level'] >= 5) {
$name = "*{$name}*"; $name = "*{$name}*";
} }
@@ -190,23 +221,23 @@ class che_발령 extends Command\NationCommand{
} }
ob_start(); ob_start();
?> ?>
<?=\sammo\getMapHtml()?><br> <?= \sammo\getMapHtml() ?><br>
선택된 도시로 아국 장수를 발령합니다.<br> 선택된 도시로 아국 장수를 발령합니다.<br>
아국 도시로만 발령이 가능합니다.<br> 아국 도시로만 발령이 가능합니다.<br>
목록을 선택하거나 도시를 클릭하세요.<br> 목록을 선택하거나 도시를 클릭하세요.<br>
<select class='formInput' name="destGeneralID" id="destGeneralID" size='1' style='color:white;background-color:black;'> <select class='formInput' name="destGeneralID" id="destGeneralID" size='1' style='color:white;background-color:black;'>
<?php foreach($destGeneralList as $destGeneral): ?> <?php foreach ($destGeneralList as $destGeneral) : ?>
<option value='<?=$destGeneral['no']?>' <?=$destGeneral['color']?>><?=$destGeneral['name']?>[<?=CityConst::byID($destGeneral['city'])->name?>] <option value='<?= $destGeneral['no'] ?>' <?= $destGeneral['color'] ?>><?= $destGeneral['name'] ?>[<?= CityConst::byID($destGeneral['city'])->name ?>]
(<?=$destGeneral['leadership']?>/<?=$destGeneral['strength']?>/<?=$destGeneral['intel']?>) (<?= $destGeneral['leadership'] ?>/<?= $destGeneral['strength'] ?>/<?= $destGeneral['intel'] ?>)
&lt;병<?=number_format($destGeneral['crew'])?>/훈<?=$destGeneral['train']?>/사<?=$destGeneral['atmos']?>/<?=$destGeneral['troop']?$troops[$destGeneral['troop']]['name']:'-'?>&gt; &lt;병<?= number_format($destGeneral['crew']) ?>/훈<?= $destGeneral['train'] ?>/사<?= $destGeneral['atmos'] ?>/<?= $destGeneral['troop'] ? $troops[$destGeneral['troop']]['name'] : '-' ?>&gt;
</option> </option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'> <select class='formInput' name="destCityID" id="destCityID" size='1' style='color:white;background-color:black;'>
<?=\sammo\optionsForCities()?><br> <?= \sammo\optionsForCities() ?><br>
</select> <input type=button id="commonSubmit" value="<?=$this->getName()?>"><br> </select> <input type=button id="commonSubmit" value="<?= $this->getName() ?>"><br>
<br> <br>
<?php <?php
return ob_get_clean(); return ob_get_clean();
} }
} }
+2 -1
View File
@@ -3,7 +3,8 @@ import 'bootstrap';
import download from 'downloadjs'; import download from 'downloadjs';
import { unwrap } from "@util/unwrap"; import { unwrap } from "@util/unwrap";
import { isInteger } from 'lodash'; import { isInteger } from 'lodash';
import { combineArray, errUnknown, getNpcColor } from '@/common_legacy'; import { errUnknown, getNpcColor } from '@/common_legacy';
import { combineArray } from "@util/combineArray";
import { isBrightColor } from "@util/isBrightColor"; import { isBrightColor } from "@util/isBrightColor";
import { numberWithCommas } from "@util/numberWithCommas"; import { numberWithCommas } from "@util/numberWithCommas";
import { unwrap_any } from '@util/unwrap_any'; import { unwrap_any } from '@util/unwrap_any';
-10
View File
@@ -69,16 +69,6 @@ export function combineObject<K extends string, V>(item: V[], columnList: K[]):
return newItem; return newItem;
} }
export function combineArray<K extends string, V>(array: V[][], columnList: K[]): Record<K, V>[] {
const result: Record<K, V>[] = [];
for (const key of array.keys()) {
const item = array[key];
result[key] = combineObject(item, columnList);
}
return result;
}
export function errUnknown(): void { export function errUnknown(): void {
alert('작업을 실패했습니다.'); alert('작업을 실패했습니다.');
} }
+1 -2
View File
@@ -6,14 +6,13 @@
:group-select="false" :group-select="false"
label="searchText" label="searchText"
track-by="value" track-by="value"
open-direction="bottom"
:show-labels="false" :show-labels="false"
selectLabel="선택(엔터)" selectLabel="선택(엔터)"
selectGroupLabel="" selectGroupLabel=""
selectedLabel="선택됨" selectedLabel="선택됨"
deselectLabel="해제(엔터)" deselectLabel="해제(엔터)"
deselectGroupLabel="" deselectGroupLabel=""
placeholder=" 선택" placeholder="도시 선택"
:maxHeight="400" :maxHeight="400"
:searchable="searchMode" :searchable="searchMode"
> >
+10 -7
View File
@@ -17,7 +17,7 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<CitySelect :cities="citiesMap" :modelValue="selectedCityID" /> <CitySelect :cities="citiesMap" v-model="selectedCityID" />
</div> </div>
<div class="col"> <div class="col">
<b-button @click="submit">{{ commandName }}</b-button> <b-button @click="submit">{{ commandName }}</b-button>
@@ -44,10 +44,14 @@ import { Args } from "@/processing/args";
import TopBackBar from "@/components/TopBackBar.vue"; import TopBackBar from "@/components/TopBackBar.vue";
import BottomBar from "@/components/BottomBar.vue"; import BottomBar from "@/components/BottomBar.vue";
declare const mapTheme: string; declare const mapTheme: string;
declare const cities: [number, string][];
declare const currentCity: number;
declare const distanceList: Record<number, number[]>;
declare const commandName: string; declare const commandName: string;
declare const currentCity: number;
declare const procRes: {
distanceList: Record<number, number[]>,
cities: [number, string][],
}
export default defineComponent({ export default defineComponent({
components: { components: {
MapLegacyTemplate, MapLegacyTemplate,
@@ -69,10 +73,9 @@ export default defineComponent({
info?: string; info?: string;
} }
>(); >();
for (const [id, name] of cities) { for (const [id, name] of procRes.cities) {
citiesMap.set(id, { name }); citiesMap.set(id, { name });
} }
console.log(citiesMap);
const selectedCityID = ref(currentCity); const selectedCityID = ref(currentCity);
@@ -94,7 +97,7 @@ export default defineComponent({
citiesMap: ref(citiesMap), citiesMap: ref(citiesMap),
selectedCityID, selectedCityID,
selectedCityObj: ref(undefined as MapCityParsed | undefined), selectedCityObj: ref(undefined as MapCityParsed | undefined),
distanceList, distanceList: procRes.distanceList,
commandName, commandName,
selected, selected,
submit, submit,
+7 -6
View File
@@ -17,7 +17,7 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<CitySelect :cities="citiesMap" :modelValue="selectedCityID" /> <CitySelect :cities="citiesMap" v-model="selectedCityID" />
</div> </div>
<div class="col"> <div class="col">
<b-button @click="submit">{{ commandName }}</b-button> <b-button @click="submit">{{ commandName }}</b-button>
@@ -44,10 +44,12 @@ import { Args } from "@/processing/args";
import TopBackBar from "@/components/TopBackBar.vue"; import TopBackBar from "@/components/TopBackBar.vue";
import BottomBar from "@/components/BottomBar.vue"; import BottomBar from "@/components/BottomBar.vue";
declare const mapTheme: string; declare const mapTheme: string;
declare const cities: [number, string][];
declare const currentCity: number; declare const currentCity: number;
declare const distanceList: Record<number, number[]>;
declare const commandName: string; declare const commandName: string;
declare const procRes: {
distanceList: Record<number, number[]>,
cities: [number, string][],
}
export default defineComponent({ export default defineComponent({
components: { components: {
MapLegacyTemplate, MapLegacyTemplate,
@@ -69,10 +71,9 @@ export default defineComponent({
info?: string; info?: string;
} }
>(); >();
for (const [id, name] of cities) { for (const [id, name] of procRes.cities) {
citiesMap.set(id, { name }); citiesMap.set(id, { name });
} }
console.log(citiesMap);
const selectedCityID = ref(currentCity); const selectedCityID = ref(currentCity);
@@ -94,7 +95,7 @@ export default defineComponent({
citiesMap: ref(citiesMap), citiesMap: ref(citiesMap),
selectedCityID, selectedCityID,
selectedCityObj: ref(undefined as MapCityParsed | undefined), selectedCityObj: ref(undefined as MapCityParsed | undefined),
distanceList, distanceList: procRes.distanceList,
commandName, commandName,
selected, selected,
submit, submit,
+5 -4
View File
@@ -17,7 +17,7 @@
</div> </div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<CitySelect :cities="citiesMap" :modelValue="selectedCityID" /> <CitySelect :cities="citiesMap" v-model="selectedCityID" />
</div> </div>
<div class="col"> <div class="col">
<b-button @click="submit">{{ commandName }}</b-button> <b-button @click="submit">{{ commandName }}</b-button>
@@ -38,9 +38,11 @@ import { Args } from "@/processing/args";
import TopBackBar from "@/components/TopBackBar.vue"; import TopBackBar from "@/components/TopBackBar.vue";
import BottomBar from "@/components/BottomBar.vue"; import BottomBar from "@/components/BottomBar.vue";
declare const mapTheme: string; declare const mapTheme: string;
declare const cities: [number, string][];
declare const currentCity: number; declare const currentCity: number;
declare const commandName: string; declare const commandName: string;
declare const procRes: {
cities: [number, string][],
}
export default defineComponent({ export default defineComponent({
components: { components: {
MapLegacyTemplate, MapLegacyTemplate,
@@ -61,10 +63,9 @@ export default defineComponent({
info?: string; info?: string;
} }
>(); >();
for (const [id, name] of cities) { for (const [id, name] of procRes.cities) {
citiesMap.set(id, { name }); citiesMap.set(id, { name });
} }
console.log(citiesMap);
const selectedCityID = ref(currentCity); const selectedCityID = ref(currentCity);
+95
View File
@@ -0,0 +1,95 @@
<template>
<v-multiselect
v-model="selectedGeneral"
:allow-empty="false"
:options="forFind"
:group-select="false"
label="searchText"
track-by="value"
:show-labels="false"
selectLabel="선택(엔터)"
selectGroupLabel=""
selectedLabel="선택됨"
deselectLabel="해제(엔터)"
deselectGroupLabel=""
placeholder="장수 선택"
:maxHeight="400"
:searchable="searchMode"
>
<template v-slot:option="props">
{{ props.option.title }}
</template>
<template v-slot:singleLabel="props">
{{ props.option.simpleName }}
</template>
</v-multiselect>
</template>
<script lang="ts">
import { filter초성withAlphabet } from "@/util/filter초성withAlphabet";
import { defineComponent, PropType } from "vue";
import { procGeneralList, procTroopList } from './processingRes';
type SelectedGeneral = {
value: number;
searchText: string;
title: string;
simpleName: string;
};
export default defineComponent({
props: {
modelValue: {
type: Number,
required: true,
},
generals: {
type: Array as PropType<procGeneralList>,
required: true,
},
cities: {
type: Map as PropType<Map<number, { name: string; info?: string }>>,
required: true,
},
troops: {
type: Object as PropType<procTroopList>,
}
},
emits: ["update:modelValue"],
watch: {
modelValue(val: number) {
const target = this.targets.get(val);
this.selectedGeneral = target;
},
selectedGeneral(val: SelectedGeneral){
this.$emit('update:modelValue', val.value);
}
},
data() {
const forFind = [];
const targets = new Map<number, SelectedGeneral>();
let selectedGeneral;
for (const gen of this.generals) {
const [filteredTextH, filteredTextA] = filter초성withAlphabet(gen.name);
const obj: SelectedGeneral = {
value: gen.no,
title: `${gen.name}[${this.cities.get(gen.cityID)?.name}] (${gen.leadership}/${gen.leadership}/${gen.intel}) <병${gen.crew.toLocaleString()}/훈${gen.train}/사${gen.atmos}`,
simpleName: gen.name,
searchText: `${gen.name} ${filteredTextH} ${filteredTextA}`
};
if (gen.no == this.modelValue) {
selectedGeneral = obj;
}
forFind.push(obj);
targets.set(gen.no, obj);
}
return {
selectedGeneral,
searchMode: true,
forFind,
targets,
};
},
});
</script>
+124 -2
View File
@@ -1,7 +1,129 @@
<template>
<TopBackBar :title="commandName" type="chief" />
<div class="bg0">
<MapLegacyTemplate
:isDetailMap="false"
:clickableAll="true"
:neutralView="true"
:useCachedMap="true"
:mapTheme="mapTheme"
v-model="selectedCityObj"
/>
<div>
선택된 도시로 아국 장수를 발령합니다.<br />
아국 도시로만 발령이 가능합니다.<br />
목록을 선택하거나 도시를 클릭하세요.<br />
</div>
<div class="row">
<div class="col-12 col-md-4">
<GeneralSelect
:cities="citiesMap"
:generals="generalList"
:troops="troops"
v-model="selectedGeneralID"
/>
</div>
<div class="col-12 col-md-4">
<CitySelect :cities="citiesMap" v-model="selectedCityID" />
</div>
<div class="col-12 col-md-4">
<b-button @click="submit">{{ commandName }}</b-button>
</div>
</div>
</div>
<BottomBar :title="commandName" />
</template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import MapLegacyTemplate, {
MapCityParsed,
} from "@/components/MapLegacyTemplate.vue";
import CitySelect from "@/processing/CitySelect.vue";
import GeneralSelect from "@/processing/GeneralSelect.vue";
import { defineComponent, ref } from "vue";
import { unwrap } from "@/util/unwrap";
import { Args } from "@/processing/args";
import TopBackBar from "@/components/TopBackBar.vue";
import BottomBar from "@/components/BottomBar.vue";
import {
convertGeneralList,
procGeneralKeyList,
procGeneralRawItemList,
procTroopList,
} from "../processingRes";
declare const mapTheme: string;
declare const currentCity: number;
declare const commandName: string;
declare const procRes: {
distanceList: Record<number, number[]>;
cities: [number, string][];
troops: procTroopList;
generals: procGeneralRawItemList;
generalsKey: procGeneralKeyList;
};
export default defineComponent({ export default defineComponent({
}); components: {
MapLegacyTemplate,
CitySelect,
GeneralSelect,
TopBackBar,
BottomBar,
},
watch: {
selectedCityObj(city: MapCityParsed) {
this.selectedCityID = city.id;
},
},
setup() {
const citiesMap = new Map<
number,
{
name: string;
info?: string;
}
>();
for (const [id, name] of procRes.cities) {
citiesMap.set(id, { name });
}
const generalList = convertGeneralList(
procRes.generalsKey,
procRes.generals
);
const selectedCityID = ref(currentCity);
function selectedCity(cityID: number) {
selectedCityID.value = cityID;
}
const selectedGeneralID = ref(generalList[0].no);
async function submit(e: Event) {
const event = new CustomEvent<Args>("customSubmit", {
detail: {
destCityID: selectedCityID.value,
destGeneralID: selectedGeneralID.value,
},
});
unwrap(e.target).dispatchEvent(event);
}
return {
mapTheme: ref(mapTheme),
citiesMap: ref(citiesMap),
selectedCityID,
selectedGeneralID,
selectedCityObj: ref(undefined as MapCityParsed | undefined),
distanceList: procRes.distanceList,
troops: procRes.troops,
generalList,
commandName,
selectedCity,
submit,
};
},
});
</script> </script>
+2 -2
View File
@@ -1,2 +1,2 @@
export * as che_발령 from "./che_발령.vue"; export { default as che_발령 } from "./che_발령.vue";
export * as che_포상 from "./che_포상.vue"; export { default as che_포상 } from "./che_포상.vue";
+54
View File
@@ -0,0 +1,54 @@
import { combineArray } from "@/util/combineArray";
export type procGeneralItem = {
no: number,
name: string,
officerLevel: number,
npc: number,
gold: number,
rice: number,
leadership: number,
strength: number,
intel: number,
cityID: number,
crew: number,
train: number,
atmos: number,
troopID: number,
}
export type procGeneralList = procGeneralItem[];
export type procGeneralKeyList = [
'no', 'name', 'officerLevel', 'npc', 'gold', 'rice', 'leadership', 'strength', 'intel', 'cityID', 'crew', 'train', 'atmos', 'troopID'
];
export type procGeneralRawItem = [
procGeneralItem[procGeneralKeyList[0]],
procGeneralItem[procGeneralKeyList[1]],
procGeneralItem[procGeneralKeyList[2]],
procGeneralItem[procGeneralKeyList[3]],
procGeneralItem[procGeneralKeyList[4]],
procGeneralItem[procGeneralKeyList[5]],
procGeneralItem[procGeneralKeyList[6]],
procGeneralItem[procGeneralKeyList[7]],
procGeneralItem[procGeneralKeyList[8]],
procGeneralItem[procGeneralKeyList[9]],
procGeneralItem[procGeneralKeyList[10]],
procGeneralItem[procGeneralKeyList[11]],
procGeneralItem[procGeneralKeyList[12]],
procGeneralItem[procGeneralKeyList[13]],
];
export type procTroopItem = {
troop_leader: number,
nation: number,
name: string
};
export type procTroopList = Record<number, procTroopItem>;
export type procGeneralRawItemList = procGeneralRawItem[];
export function convertGeneralList(keys: procGeneralKeyList, rawList: procGeneralRawItemList): procGeneralList{
return combineArray(rawList, keys) as procGeneralList;
}
+11
View File
@@ -0,0 +1,11 @@
import { combineObject } from "../common_legacy";
export function combineArray<K extends string, V>(array: V[][], columnList: K[]): Record<K, V>[] {
const result: Record<K, V>[] = [];
for (const key of array.keys()) {
const item = array[key];
result[key] = combineObject(item, columnList);
}
return result;
}
+6 -1
View File
@@ -79,13 +79,15 @@ const app: App<Element> | undefined = (function () {
const moduleName = entryInfo[1]; const moduleName = entryInfo[1];
if (!(moduleName in GeneralActions)) { if (!(moduleName in GeneralActions)) {
console.error(`${moduleName}${groupName}에 없음`); console.error(`${moduleName}${groupName}에 없음`);
return undefined;
} }
return createApp(GeneralActions[moduleName]); return createApp(GeneralActions[moduleName]);
} }
if (groupName == 'Nation') { if (groupName == 'Nation') {
const moduleName = entryInfo[1]; const moduleName = entryInfo[1];
if (!(moduleName in GeneralActions)) { if (!(moduleName in NationActions)) {
console.error(`${moduleName}${groupName}에 없음`); console.error(`${moduleName}${groupName}에 없음`);
return undefined;
} }
return createApp(NationActions[moduleName]); return createApp(NationActions[moduleName]);
} }
@@ -95,6 +97,9 @@ const app: App<Element> | undefined = (function () {
}()); }());
if (app === undefined) { if (app === undefined) {
const div = document.createElement('div');
div.innerHTML = `모듈의 view가 없습니다. ${JSON.stringify(entryInfo)}`;
document.body.appendChild(div);
console.error(`모듈이 지정되지 않음`, entryInfo); console.error(`모듈이 지정되지 않음`, entryInfo);
} }
else { else {