From 7a3642296aa830f60483473cab003179b3df5a69 Mon Sep 17 00:00:00 2001 From: Hide_D Date: Fri, 24 Feb 2023 00:25:29 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=A0=84=ED=88=AC=20=EC=8B=9C=EB=AE=AC?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=ED=84=B0=EC=97=90=20=ED=9E=88=EB=93=A0=20?= =?UTF-8?q?=EB=B2=84=ED=94=84=20=EB=B0=98=EC=98=81=20=EA=B0=80=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hwe/battle_simulator.php | 19 + hwe/j_simulate_battle.php | 40 + hwe/ts/battle_simulator.ts | 1971 ++++++++++++++++++------------------ 3 files changed, 1059 insertions(+), 971 deletions(-) diff --git a/hwe/battle_simulator.php b/hwe/battle_simulator.php index 384d3ed5..0cb0738a 100644 --- a/hwe/battle_simulator.php +++ b/hwe/battle_simulator.php @@ -434,6 +434,25 @@ if ($nationID) { + +
+
자신
+
회피 확률
+ +
필살 확률
+ +
계략 시도 확률
+ +
+
+
상대
+
회피 확률
+ +
필살 확률
+ +
계략 시도 확률
+ +
diff --git a/hwe/j_simulate_battle.php b/hwe/j_simulate_battle.php index 149288cc..c66c0e6b 100644 --- a/hwe/j_simulate_battle.php +++ b/hwe/j_simulate_battle.php @@ -133,6 +133,19 @@ $generalCheck = [ ['weapon', array_merge(array_keys(GameConst::$allItems['weapon']), ['None'])], ['book', array_merge(array_keys(GameConst::$allItems['book']), ['None'])], ['item', array_merge(array_keys(GameConst::$allItems['item']), ['None'])], + ], + 'array'=>['inheritBuff'], +]; + +$inheritBuffCheck = [ + 'between'=>[ + [TriggerInheritBuff::WAR_AVOID_RATIO, [0, 5]], + [TriggerInheritBuff::WAR_CRITICAL_RATIO, [0, 5]], + [TriggerInheritBuff::WAR_MAGIC_TRIAL_PROB, [0, 5]], + + [TriggerInheritBuff::OPPOSE_WAR_AVOID_RATIO, [0, 5]], + [TriggerInheritBuff::OPPOSE_WAR_CRITICAL_RATIO, [0, 5]], + [TriggerInheritBuff::OPPOSE_WAR_MAGIC_TRIAL_PROB, [0, 5]], ] ]; @@ -144,6 +157,19 @@ if(!$v->validate()){ 'reason'=>'[출병자]'.$v->errorStr() ]); } +$rawAttacker['aux'] = []; +if(key_exists('inheritBuff', $rawAttacker)){ + $v = new Validator($rawAttacker['inheritBuff']); + $v->rules($inheritBuffCheck); + if(!$v->validate()){ + Json::die([ + 'result'=>false, + 'reason'=>'[출병자]'.$v->errorStr() + ]); + } + $rawAttacker['aux']['inheritBuff'] = $rawAttacker['inheritBuff']; +} +$rawAttacker['aux'] = Json::encode($rawAttacker['aux']); $rawAttacker['owner'] = 0; $defenderList = []; @@ -157,6 +183,20 @@ foreach($rawDefenderList as $idx=>$rawDefenderGeneral){ 'reason'=>"[수비자{$idx}]".$v->errorStr() ]); } + $rawDefenderGeneral['aux'] = []; + if(key_exists('inheritBuff', $rawDefenderGeneral)){ + $v = new Validator($rawDefenderGeneral['inheritBuff']); + $v->rules($inheritBuffCheck); + if(!$v->validate()){ + $idx+=1; + Json::die([ + 'result'=>false, + 'reason'=>"[수비자{$idx}]".$v->errorStr() + ]); + } + $rawDefenderGeneral['aux']['inheritBuff'] = $rawDefenderGeneral['inheritBuff']; + } + $rawDefenderGeneral['aux'] = Json::encode($rawDefenderGeneral['aux']); $rawDefenderGeneral['owner'] = 0; $defenderList[] = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), $rawDefenderCity, $rawAttackerNation, $year, $month, true); diff --git a/hwe/ts/battle_simulator.ts b/hwe/ts/battle_simulator.ts index 9d5f98d0..3ec66582 100644 --- a/hwe/ts/battle_simulator.ts +++ b/hwe/ts/battle_simulator.ts @@ -1,1079 +1,1108 @@ -import $ from 'jquery'; -import 'bootstrap'; -import download from 'downloadjs'; +import $ from "jquery"; +import "bootstrap"; +import download from "downloadjs"; import { unwrap } from "@util/unwrap"; -import { isInteger } from 'lodash-es'; -import { errUnknown } from '@/common_legacy'; -import { getNPCColor } from './utilGame'; +import { isInteger } from "lodash-es"; +import { errUnknown } from "@/common_legacy"; +import { getNPCColor } from "./utilGame"; import { combineArray } from "@util/combineArray"; import { isBrightColor } from "@util/isBrightColor"; import { numberWithCommas } from "@util/numberWithCommas"; -import { unwrap_any } from '@util/unwrap_any'; -import type { BasicGeneralListResponse, InvalidResponse } from '@/defs'; -import { formatTime } from '@util/formatTime'; -import { Modal } from 'bootstrap'; +import { unwrap_any } from "@util/unwrap_any"; +import type { BasicGeneralListResponse, InvalidResponse } from "@/defs"; +import { formatTime } from "@util/formatTime"; +import { Modal } from "bootstrap"; type CityAttackerInfo = { - level: number, -} + level: number; +}; type CityBasicInfo = { - nation?: number, - level: number, - def: number, - wall: number, - city?: number, -} + nation?: number; + level: number; + def: number; + wall: number; + city?: number; +}; type NationBasicInfo = { - level: number, - type: string, - tech: number, - capital: number, -} + level: number; + type: string; + tech: number; + capital: number; +}; + +type InheritBuff = { + warAvoidRatio: number; + warCriticalRatio: number; + warMagicTrialProb: number; + warAvoidRatioOppose: number; + warCriticalRatioOppose: number; + warMagicTrialProbOppose: number; +}; type GeneralInfo = { - no: number, - npc?: number - name: string, - officer_level: number, - explevel: number, + no: number; + npc?: number; + name: string; + officer_level: number; + explevel: number; - leadership: number, - horse: string, - strength: number, - weapon: string, - intel: number, - book: string, - item: string, + leadership: number; + horse: string; + strength: number; + weapon: string; + intel: number; + book: string; + item: string; - injury: number, + injury: number; - rice: number, + rice: number; - personal: string, - special2: string, + personal: string; + special2: string; - crew: number, - crewtype: number, - atmos: number, - train: number, + crew: number; + crewtype: number; + atmos: number; + train: number; - dex1: number, - dex2: number, - dex3: number, - dex4: number, - dex5: number, + dex1: number; + dex2: number; + dex3: number; + dex4: number; + dex5: number; - defence_train: number, + defence_train: number; - warnum: number, - killnum: number, - killcrew: number, + warnum: number; + killnum: number; + killcrew: number; - officer_city?: number, + officer_city?: number; + + inheritBuff?: InheritBuff; }; type BattleInfo = { - attackerGeneral: GeneralInfo, - attackerCity: CityAttackerInfo | CityBasicInfo, - attackerNation: NationBasicInfo, - defenderGenerals: GeneralInfo[], - defenderCity: CityBasicInfo, - defenderNation: NationBasicInfo, - year: number, - month: number, - repeatCnt: number, - seed?: string, + attackerGeneral: GeneralInfo; + attackerCity: CityAttackerInfo | CityBasicInfo; + attackerNation: NationBasicInfo; + defenderGenerals: GeneralInfo[]; + defenderCity: CityBasicInfo; + defenderNation: NationBasicInfo; + year: number; + month: number; + repeatCnt: number; + seed?: string; }; type ExportedGeneralInfo = { - objType: 'general', - data: GeneralInfo, -} + objType: "general"; + data: GeneralInfo; +}; type ExportedBattleInfo = { - objType: 'battle', - data: BattleInfo -} + objType: "battle"; + data: BattleInfo; +}; type ExportedInfo = ExportedGeneralInfo | ExportedBattleInfo; type BattleResult = { - result: true, - datetime: string, - lastWarLog: { - generalBattleResultLog: string, - generalBattleDetailLog: string, - }, - avgWar: number, - phase: number, - killed: number, - maxKilled: number, - minKilled: number, - dead: number, - maxDead: number, - minDead: number, - attackerRice: number, - defenderRice: number, - attackerSkills: Record, - defendersSkills: Record[], -} + result: true; + datetime: string; + lastWarLog: { + generalBattleResultLog: string; + generalBattleDetailLog: string; + }; + avgWar: number; + phase: number; + killed: number; + maxKilled: number; + minKilled: number; + dead: number; + maxDead: number; + minDead: number; + attackerRice: number; + defenderRice: number; + attackerSkills: Record; + defendersSkills: Record[]; +}; declare global { - interface Window { - nation?: NationBasicInfo, - city?: CityBasicInfo, - defaultSpecialDomestic: string, - } + interface Window { + nation?: NationBasicInfo; + city?: CityBasicInfo; + defaultSpecialDomestic: string; + } } -let modalImport: Modal|undefined = undefined; +let modalImport: Modal | undefined = undefined; $(function ($) { + const $generalForm = $(".form_sample .general_detail"); + const $defenderHeaderForm = $(".form_sample .card-header"); + const $defenderColumn = $(".defender-column"); + const defenderNoList: Record> = {}; - const $generalForm = $('.form_sample .general_detail'); - const $defenderHeaderForm = $('.form_sample .card-header'); - const $defenderColumn = $('.defender-column'); + const $attackerCard = $(".attacker_form"); - const defenderNoList: Record> = {}; - - const $attackerCard = $('.attacker_form'); - - const initBasicEvent = function () { - - if (window.nation && window.city) { - $('.form_city_level').val(window.city.level); - $('.form_def').val(window.city.def); - $('.form_wall').val(window.city.wall); - $('.form_nation_type').val(window.nation.type); - $('.form_nation_level').val(window.nation.level); - $('.form_tech').val(window.nation.tech / 1000); - if (window.nation.capital == window.city.city) { - $('.attacker_nation .form_is_capital:first').trigger('click'); - $('.defender_nation .form_is_capital:first').trigger('click'); - } else { - $('.attacker_nation .form_is_capital:last').trigger('click'); - $('.defender_nation .form_is_capital:last').trigger('click'); - } - } else { - $('.attacker_nation .form_is_capital:last').trigger('click'); - $('.defender_nation .form_is_capital:last').trigger('click'); - } - - $('.form_injury').on('change', function () { - const $this = $(this) as JQuery; - const $general = getGeneralDetail($this); - const $helptext = $general.find('.injury_helptext'); - - const injury = parseInt($this.val() as string); - //FIXME: PHP 코드와 항상 일치하도록 변경 - let text = '건강'; - let color = 'white'; - if (injury > 60) { - text = '위독'; - color = 'red'; - } else if (injury > 40) { - text = '심각'; - color = 'magenta'; - } else if (injury > 20) { - text = '중상'; - color = 'orange'; - } else if (injury > 0) { - text = '경상'; - color = 'yellow'; - } - $helptext.html(text).css('color', color); - }); - - $('.export_general').on('click', function () { - const $btn = $(this); - const $general = getGeneralDetail($btn); - - const values = exportGeneralInfo($general); - console.log(values); - }); - $('.delete-defender').on('click', function () { - const $card = getGeneralFrame($(this)); - deleteDefender($card); - }); - $('.copy-defender').on('click', function () { - const $card = getGeneralFrame($(this)); - copyDefender($card); - }); - - $('.add-defender').on('click', function () { - addDefender(); - }); - - $('.btn-general-load').on('click', function () { - const $file = $(this).prev(); - $file[0].click(); - }) - - $('.form_load_general_file').on('change', function (e) { - e.preventDefault(); - const $this = $(this); - const $card = getGeneralFrame($this); - - const files = unwrap(e.target.files); - - importGeneralInfoByFile(files, $card); - return false; - }); - - $('.btn-general-import-server').on('click', function () { - const $this = $(this); - const $card = getGeneralFrame($this); - - const $modal = $('#importModal'); - $modal.data('target', $card); - if(!modalImport){ - modalImport = new Modal($modal[0]); - } - modalImport.show(); - }); - - $('.btn-general-save').on('click', function () { - const $this = $(this); - const $general = getGeneralDetail($this); - const generalData = exportGeneralInfo($general); - - const filename = `general_${generalData.name}.json`; - const saveData = JSON.stringify({ - objType: 'general', - data: generalData - }, null, 4); - - download(saveData, filename, 'application/json'); - }); - - $('.btn-battle-load').on('click', function () { - const $file = $(this).prev(); - $file[0].click(); - }) - - $('.form_load_battle_file').on('change', function (e) { - e.preventDefault(); - const files = unwrap(e.target.files); - - importBattleInfoByFile(files); - return false; - }); - - $('.btn-battle-save').on('click', function () { - const battleData = exportAllData(); - const dateText = formatTime(new Date(), 'yyyyMMdd_HHmmss'); - const filename = `battle_${dateText}.json`; - const saveData = JSON.stringify({ - objType: 'battle', - data: battleData - }, null, 4); - - download(saveData, filename, 'application/json'); - }) - - const $generals = $('.general_detail'); - $generals.on('dragover dragleave', function (e) { - e.stopPropagation() - e.preventDefault() - }) - $generals.on('drop', function (e) { - e.preventDefault(); - const $this = $(this); - const $card = getGeneralFrame($this); - - const files = unwrap((unwrap(e.originalEvent) as DragEvent).dataTransfer).files; - - importGeneralInfoByFile(files, $card); - return false; - }); - - const $battlePad = $('.dragpad_battle'); - $battlePad.on('dragover dragleave', function (e) { - e.stopPropagation() - e.preventDefault() - }) - $battlePad.on('drop', function (e) { - e.preventDefault(); - - const files = unwrap((unwrap(e.originalEvent) as DragEvent).dataTransfer).files; - - importBattleInfoByFile(files); - return false; - }); + const initBasicEvent = function () { + if (window.nation && window.city) { + $(".form_city_level").val(window.city.level); + $(".form_def").val(window.city.def); + $(".form_wall").val(window.city.wall); + $(".form_nation_type").val(window.nation.type); + $(".form_nation_level").val(window.nation.level); + $(".form_tech").val(window.nation.tech / 1000); + if (window.nation.capital == window.city.city) { + $(".attacker_nation .form_is_capital:first").trigger("click"); + $(".defender_nation .form_is_capital:first").trigger("click"); + } else { + $(".attacker_nation .form_is_capital:last").trigger("click"); + $(".defender_nation .form_is_capital:last").trigger("click"); + } + } else { + $(".attacker_nation .form_is_capital:last").trigger("click"); + $(".defender_nation .form_is_capital:last").trigger("click"); } - const importGeneralInfo = function ($general: JQuery, data: GeneralInfo) { - const setVal = function (query: string, val: string | number) { - $general.find(query).val(val).trigger('change'); - } + $(".form_injury").on("change", function () { + const $this = $(this) as JQuery; + const $general = getGeneralDetail($this); + const $helptext = $general.find(".injury_helptext"); - setVal('.form_general_name', data.name); + const injury = parseInt($this.val() as string); + //FIXME: PHP 코드와 항상 일치하도록 변경 + let text = "건강"; + let color = "white"; + if (injury > 60) { + text = "위독"; + color = "red"; + } else if (injury > 40) { + text = "심각"; + color = "magenta"; + } else if (injury > 20) { + text = "중상"; + color = "orange"; + } else if (injury > 0) { + text = "경상"; + color = "yellow"; + } + $helptext.html(text).css("color", color); + }); - setVal('.form_officer_level', data.officer_level); - setVal('.form_exp_level', data.explevel); + $(".export_general").on("click", function () { + const $btn = $(this); + const $general = getGeneralDetail($btn); - setVal('.form_leadership', data.leadership); - setVal('.form_general_horse', data.horse); - setVal('.form_strength', data.strength); - setVal('.form_general_weap', data.weapon); - setVal('.form_intel', data.intel); - setVal('.form_general_book', data.book); - setVal('.form_general_item', data.item); + const values = exportGeneralInfo($general); + console.log(values); + }); + $(".delete-defender").on("click", function () { + const $card = getGeneralFrame($(this)); + deleteDefender($card); + }); + $(".copy-defender").on("click", function () { + const $card = getGeneralFrame($(this)); + copyDefender($card); + }); - setVal('.form_injury', data.injury); + $(".add-defender").on("click", function () { + addDefender(); + }); - setVal('.form_rice', data.rice); + $(".btn-general-load").on("click", function () { + const $file = $(this).prev(); + $file[0].click(); + }); - setVal('.form_general_character', data.personal); - setVal('.form_general_special_war', data.special2); + $(".form_load_general_file").on("change", function (e) { + e.preventDefault(); + const $this = $(this); + const $card = getGeneralFrame($this); - setVal('.form_crew', data.crew); - setVal('.form_crewtype', data.crewtype); - setVal('.form_atmos', data.atmos); - setVal('.form_train', data.train); + const files = unwrap(e.target.files); - setVal('.form_dex1', data.dex1); - setVal('.form_dex2', data.dex2); - setVal('.form_dex3', data.dex3); - setVal('.form_dex4', data.dex4); - setVal('.form_dex5', data.dex5); - setVal('.form_defence_train', data.defence_train); + importGeneralInfoByFile(files, $card); + return false; + }); - setVal('.form_warnum', data.warnum); - setVal('.form_killnum', data.killnum); - setVal('.form_killcrew', data.killcrew); + $(".btn-general-import-server").on("click", function () { + const $this = $(this); + const $card = getGeneralFrame($this); - if (!setGeneralNo($general, data.no)) { - setGeneralNo($general, generateNewGeneralNo()); - } + const $modal = $("#importModal"); + $modal.data("target", $card); + if (!modalImport) { + modalImport = new Modal($modal[0]); + } + modalImport.show(); + }); + + $(".btn-general-save").on("click", function () { + const $this = $(this); + const $general = getGeneralDetail($this); + const generalData = exportGeneralInfo($general); + + const filename = `general_${generalData.name}.json`; + const saveData = JSON.stringify( + { + objType: "general", + data: generalData, + }, + null, + 4 + ); + + download(saveData, filename, "application/json"); + }); + + $(".btn-battle-load").on("click", function () { + const $file = $(this).prev(); + $file[0].click(); + }); + + $(".form_load_battle_file").on("change", function (e) { + e.preventDefault(); + const files = unwrap(e.target.files); + + importBattleInfoByFile(files); + return false; + }); + + $(".btn-battle-save").on("click", function () { + const battleData = exportAllData(); + const dateText = formatTime(new Date(), "yyyyMMdd_HHmmss"); + const filename = `battle_${dateText}.json`; + const saveData = JSON.stringify( + { + objType: "battle", + data: battleData, + }, + null, + 4 + ); + + download(saveData, filename, "application/json"); + }); + + const $generals = $(".general_detail"); + $generals.on("dragover dragleave", function (e) { + e.stopPropagation(); + e.preventDefault(); + }); + $generals.on("drop", function (e) { + e.preventDefault(); + const $this = $(this); + const $card = getGeneralFrame($this); + + const files = unwrap((unwrap(e.originalEvent) as DragEvent).dataTransfer).files; + + importGeneralInfoByFile(files, $card); + return false; + }); + + const $battlePad = $(".dragpad_battle"); + $battlePad.on("dragover dragleave", function (e) { + e.stopPropagation(); + e.preventDefault(); + }); + $battlePad.on("drop", function (e) { + e.preventDefault(); + + const files = unwrap((unwrap(e.originalEvent) as DragEvent).dataTransfer).files; + + importBattleInfoByFile(files); + return false; + }); + }; + + const importGeneralInfo = function ($general: JQuery, data: GeneralInfo) { + const setVal = function (query: string, val: string | number) { + $general.find(query).val(val).trigger("change"); + }; + + setVal(".form_general_name", data.name); + + setVal(".form_officer_level", data.officer_level); + setVal(".form_exp_level", data.explevel); + + setVal(".form_leadership", data.leadership); + setVal(".form_general_horse", data.horse); + setVal(".form_strength", data.strength); + setVal(".form_general_weap", data.weapon); + setVal(".form_intel", data.intel); + setVal(".form_general_book", data.book); + setVal(".form_general_item", data.item); + + setVal(".form_injury", data.injury); + + setVal(".form_rice", data.rice); + + setVal(".form_general_character", data.personal); + setVal(".form_general_special_war", data.special2); + + setVal(".form_crew", data.crew); + setVal(".form_crewtype", data.crewtype); + setVal(".form_atmos", data.atmos); + setVal(".form_train", data.train); + + setVal(".form_dex1", data.dex1); + setVal(".form_dex2", data.dex2); + setVal(".form_dex3", data.dex3); + setVal(".form_dex4", data.dex4); + setVal(".form_dex5", data.dex5); + setVal(".form_defence_train", data.defence_train); + + setVal(".form_warnum", data.warnum); + setVal(".form_killnum", data.killnum); + setVal(".form_killcrew", data.killcrew); + + if (data.inheritBuff) { + setVal(".form_war_avoid_ratio", data.inheritBuff.warAvoidRatio); + setVal(".form_war_critical_ratio", data.inheritBuff.warCriticalRatio); + setVal(".form_war_magic_trial_prob", data.inheritBuff.warMagicTrialProb); + setVal(".form_oppose_war_avoid_ratio", data.inheritBuff.warAvoidRatioOppose); + setVal(".form_oppose_war_critical_ratio", data.inheritBuff.warCriticalRatioOppose); + setVal(".form_oppose_war_magic_trial_prob", data.inheritBuff.warMagicTrialProbOppose); } - const exportGeneralInfo = function ($general: JQuery): GeneralInfo { - const getInt = function (query: string): number { - return parseInt(unwrap_any($general.find(query).val())); - } + if (!setGeneralNo($general, data.no)) { + setGeneralNo($general, generateNewGeneralNo()); + } + }; - const getVal = function (query: string): string { - return unwrap_any($general.find(query).val()); - } + const exportGeneralInfo = function ($general: JQuery): GeneralInfo { + const getInt = function (query: string): number { + return parseInt(unwrap_any($general.find(query).val())); + }; - return { - no: getGeneralNo($general), - name: getVal('.form_general_name'), - officer_level: getInt('.form_officer_level'), - explevel: getInt('.form_exp_level'), + const getVal = function (query: string): string { + return unwrap_any($general.find(query).val()); + }; - leadership: getInt('.form_leadership'), - horse: getVal('.form_general_horse'), - strength: getInt('.form_strength'), - weapon: getVal('.form_general_weap'), - intel: getInt('.form_intel'), - book: getVal('.form_general_book'), - item: getVal('.form_general_item'), + return { + no: getGeneralNo($general), + name: getVal(".form_general_name"), + officer_level: getInt(".form_officer_level"), + explevel: getInt(".form_exp_level"), - injury: getInt('.form_injury'), + leadership: getInt(".form_leadership"), + horse: getVal(".form_general_horse"), + strength: getInt(".form_strength"), + weapon: getVal(".form_general_weap"), + intel: getInt(".form_intel"), + book: getVal(".form_general_book"), + item: getVal(".form_general_item"), - rice: getInt('.form_rice'), + injury: getInt(".form_injury"), - personal: getVal('.form_general_character'), - special2: getVal('.form_general_special_war'), + rice: getInt(".form_rice"), - crew: getInt('.form_crew'), - crewtype: getInt('.form_crewtype'), - atmos: getInt('.form_atmos'), - train: getInt('.form_train'), + personal: getVal(".form_general_character"), + special2: getVal(".form_general_special_war"), - dex1: getInt('.form_dex1'), - dex2: getInt('.form_dex2'), - dex3: getInt('.form_dex3'), - dex4: getInt('.form_dex4'), - dex5: getInt('.form_dex5'), + crew: getInt(".form_crew"), + crewtype: getInt(".form_crewtype"), + atmos: getInt(".form_atmos"), + train: getInt(".form_train"), - defence_train: getInt('.form_defence_train'), + dex1: getInt(".form_dex1"), + dex2: getInt(".form_dex2"), + dex3: getInt(".form_dex3"), + dex4: getInt(".form_dex4"), + dex5: getInt(".form_dex5"), - warnum: getInt('.form_warnum'), - killnum: getInt('.form_killnum'), - killcrew: getInt('.form_killcrew'), + defence_train: getInt(".form_defence_train"), - }; + warnum: getInt(".form_warnum"), + killnum: getInt(".form_killnum"), + killcrew: getInt(".form_killcrew"), + + inheritBuff: { + warAvoidRatio: getInt(".form_war_avoid_ratio"), + warCriticalRatio: getInt(".form_war_critical_ratio"), + warMagicTrialProb: getInt(".form_war_magic_trial_prob"), + warAvoidRatioOppose: getInt(".form_oppose_war_avoid_ratio"), + warCriticalRatioOppose: getInt(".form_oppose_war_critical_ratio"), + warMagicTrialProbOppose: getInt(".form_oppose_war_magic_trial_prob"), + }, + }; + }; + + const importBattleInfoByFile = function (files: FileList) { + if (files === null) { + alert("파일 에러!"); + return false; } - const importBattleInfoByFile = function (files: FileList) { - if (files === null) { - alert('파일 에러!'); - return false; - } + if (files.length < 1) { + alert("파일 에러!"); + return false; + } - if (files.length < 1) { - alert("파일 에러!"); - return false; - } + const file = files[0]; + if (file.size > 1024 * 1024) { + alert("파일이 너무 큽니다!"); + return false; + } + if (file.type === "") { + alert("폴더를 업로드할 수 없습니다!"); + return false; + } + const reader = new FileReader(); + reader.onload = function () { + let battleData: ExportedInfo; + try { + battleData = JSON.parse(unwrap_any(reader.result)); + } catch (e) { + alert("올바르지 않은 파일 형식입니다"); + return false; + } - const file = files[0]; - if (file.size > 1024 * 1024) { - alert('파일이 너무 큽니다!'); - return false; - } - if (file.type === '') { - alert('폴더를 업로드할 수 없습니다!'); - return false; - } + if (!("objType" in battleData)) { + alert("파일 형식을 확인할 수 없습니다"); + return false; + } - const reader = new FileReader(); - reader.onload = function () { - let battleData: ExportedInfo; - try { - battleData = JSON.parse(unwrap_any(reader.result)); - } catch (e) { - alert('올바르지 않은 파일 형식입니다'); - return false; - } + if (battleData.objType != "battle") { + alert("전투 데이터가 아닙니다"); + return false; + } - if (!('objType' in battleData)) { - alert('파일 형식을 확인할 수 없습니다'); - return false; - } + importBattleInfo(battleData.data); + return true; + }; - if (battleData.objType != 'battle') { - alert('전투 데이터가 아닙니다'); - return false; - } + try { + reader.readAsText(file); + } catch (e) { + alert("파일을 읽는데 실패했습니다."); + return false; + } - importBattleInfo(battleData.data); - return true; - }; + return true; + }; - try { + const importGeneralInfoByFile = function (files: FileList, $card: JQuery) { + if ($card === undefined) { + $card = addDefender(); + } - reader.readAsText(file); - } catch (e) { - alert('파일을 읽는데 실패했습니다.'); - return false; - } + if (files === null) { + alert("파일 에러!"); + return false; + } + if (files.length < 1) { + alert("파일 에러!"); + return false; + } + + const file = files[0]; + if (file.size > 1024 * 1024) { + alert("파일이 너무 큽니다!"); + return false; + } + if (file.type === "") { + alert("폴더를 업로드할 수 없습니다!"); + return false; + } + + const reader = new FileReader(); + reader.onload = function () { + let generalData: ExportedInfo; + try { + generalData = JSON.parse(unwrap_any(reader.result)); + } catch (e) { + alert("올바르지 않은 파일 형식입니다"); + return false; + } + + if (!("objType" in generalData)) { + alert("파일 형식을 확인할 수 없습니다"); + return false; + } + + if (generalData.objType == "battle") { + importBattleInfo(generalData.data); return true; + } + if (generalData.objType != "general") { + alert("장수 데이터가 아닙니다"); + return false; + } + + $card.find(".form_load_general_file").val(""); + + importGeneralInfo($card, generalData.data); + return true; + }; + + try { + reader.readAsText(file); + } catch (e) { + alert("파일을 읽는데 실패했습니다."); + return false; } - const importGeneralInfoByFile = function (files: FileList, $card: JQuery) { - if ($card === undefined) { - $card = addDefender(); - } - - if (files === null) { - alert('파일 에러!'); - return false; - } - - if (files.length < 1) { - alert("파일 에러!"); - return false; - } - - - const file = files[0]; - if (file.size > 1024 * 1024) { - alert('파일이 너무 큽니다!'); - return false; - } - if (file.type === '') { - alert('폴더를 업로드할 수 없습니다!'); - return false; - } - - const reader = new FileReader(); - reader.onload = function () { - let generalData: ExportedInfo; - try { - generalData = JSON.parse(unwrap_any(reader.result)); - } catch (e) { - alert('올바르지 않은 파일 형식입니다'); - return false; - } - - if (!('objType' in generalData)) { - alert('파일 형식을 확인할 수 없습니다'); - return false; - } - - if (generalData.objType == 'battle') { - importBattleInfo(generalData.data); - return true; - } - if (generalData.objType != 'general') { - alert('장수 데이터가 아닙니다'); - return false; - } - - $card.find('.form_load_general_file').val(''); - - importGeneralInfo($card, generalData.data); - return true; - }; - - try { - - reader.readAsText(file); - } catch (e) { - alert('파일을 읽는데 실패했습니다.'); - return false; + return true; + }; + + const extendGeneralInfoForDB = function (generalData: GeneralInfo) { + const dbVal = { + nation: generalData.no <= 1 ? 1 : 2, + city: generalData.no <= 1 ? 1 : 3, + turntime: "2018-08-26 12:00", + special: window.defaultSpecialDomestic, + leadership_exp: 0, + strength_exp: 0, + intel_exp: 0, + + gold: 10000, + + dedication: 0, + + recent_war: "2018-08-26 12:00", + experience: Math.pow(generalData.explevel, 2), + }; + + return $.extend({}, generalData, dbVal); + }; + + const getGeneralFrame = function ($btn: JQuery) { + const $card = $btn.closest(".general_form"); + return $card; + }; + + const getGeneralDetail = function ($btn: JQuery) { + const $card = getGeneralFrame($btn); + const $general = $card.find(".general_detail"); + return $general; + }; + + const getGeneralNo = function ($btn: JQuery) { + return parseInt(getGeneralFrame($btn).data("general_no")); + }; + + const setGeneralNo = function ($btn: JQuery, value: number) { + if (value == 1) { + //1번은 무조건 공격자임 + return false; + } + if (value in defenderNoList) { + return false; + } + const $card = getGeneralFrame($btn); + $card.data("general_no", value); + defenderNoList[value] = $card; + return true; + }; + + const generateNewGeneralNo = function () { + for (;;) { + const newGeneralNo = Math.floor(Math.random() * (1 << 24)) + 2; + if (newGeneralNo in defenderNoList) { + continue; + } + return newGeneralNo; + } + }; + + const deleteGeneralNo = function ($btn: JQuery) { + const $card = getGeneralFrame($btn); + $card.removeData("general_no"); + const generalNo = getGeneralNo($card); + delete defenderNoList[generalNo]; + }; + + const addDefender = function ($cardAfter?: JQuery) { + const $newCard = $('
'); + + if ($cardAfter === undefined) { + $defenderColumn.append($newCard); + } else { + $cardAfter.after($newCard); + } + + $newCard.append($defenderHeaderForm.clone(true, true)); + $newCard.append($generalForm.clone(true, true)); + + //$newGeneral = getGeneralDetail($newCard); + setGeneralNo($newCard, generateNewGeneralNo()); + + return $newCard; + }; + + const deleteDefender = function ($card: JQuery) { + deleteGeneralNo($card); + $card.detach(); + }; + + const copyDefender = function ($card: JQuery) { + const $general = getGeneralDetail($card); + + const generalData = exportGeneralInfo($general); + const $newObj = addDefender($card); + importGeneralInfo(getGeneralDetail($newObj), generalData); + }; + + const importBattleInfo = function (battleData: BattleInfo) { + $(".form_load_battle_file").val(""); + console.log(battleData); + + const $attackerNation = $(".attacker_nation"); + const $defenderNation = $(".defender_nation"); + + const attackerGeneral = battleData.attackerGeneral; + const attackerCity = battleData.attackerCity; + const attackerNation = battleData.attackerNation; + + const defenderGenerals = battleData.defenderGenerals; + const defenderCity = battleData.defenderCity; + const defenderNation = battleData.defenderNation; + + const seed = battleData.seed; + + if (seed) { + $("#seed").val(seed); + } + + $("#year").val(battleData.year); + $("#month").val(battleData.month); + $("#repeat_cnt").val(battleData.repeatCnt); + + $(".delete-defender").trigger("click"); + + $attackerNation.find(".form_nation_type").val(attackerNation.type); + $attackerNation.find(".form_tech").val(Math.floor(attackerNation.tech / 1000)); + $attackerNation.find(".form_nation_level").val(attackerNation.level); + if (attackerNation.capital == 1) { + $attackerNation.find(".form_is_capital:first").trigger("click"); + } else { + $attackerNation.find(".form_is_capital:last").trigger("click"); + } + $attackerNation.find(".form_city_level").val(attackerCity.level); + + importGeneralInfo($(".attacker_form"), attackerGeneral); + + $defenderNation.find(".form_nation_type").val(defenderNation.type); + $defenderNation.find(".form_tech").val(Math.floor(defenderNation.tech / 1000)); + $defenderNation.find(".form_nation_level").val(defenderNation.level); + if (defenderNation.capital == 1) { + $defenderNation.find(".form_is_capital:first").trigger("click"); + } else { + $defenderNation.find(".form_is_capital:last").trigger("click"); + } + $defenderNation.find(".form_city_level").val(defenderCity.level); + $("#city_def").val(defenderCity.def); + $("#city_wall").val(defenderCity.wall); + + $.each(defenderGenerals, function (idx, defenderGeneral) { + const $card = addDefender(); + importGeneralInfo($card, defenderGeneral); + }); + }; + + const exportAllData = function (): BattleInfo { + const $attackerNation = $(".attacker_nation"); + const $defenderNation = $(".defender_nation"); + + const attackerGeneral = exportGeneralInfo($(".attacker_form")); + + const attackerCity = { + level: parseInt($attackerNation.find(".form_city_level").val() as string), + }; + + const attackerNation = { + type: unwrap_any($attackerNation.find(".form_nation_type").val()), + tech: parseInt($attackerNation.find(".form_tech").val() as string) * 1000, + level: parseInt($attackerNation.find(".form_nation_level").val() as string), + capital: $attackerNation.find(".form_is_capital:checked").val() == "1" ? 1 : 2, + }; + + const defenderGenerals = $(".defender_form") + .map(function () { + return exportGeneralInfo($(this)); + }) + .toArray(); + + const defenderCity = { + def: parseInt($("#city_def").val() as string), + wall: parseInt($("#city_wall").val() as string), + level: parseInt($defenderNation.find(".form_city_level").val() as string), + }; + + const defenderNation = { + type: unwrap_any($defenderNation.find(".form_nation_type").val()), + tech: parseInt(unwrap_any($defenderNation.find(".form_tech").val())) * 1000, + level: parseInt(unwrap_any($defenderNation.find(".form_nation_level").val())), + capital: $defenderNation.find(".form_is_capital:checked").val() == "1" ? 3 : 4, + }; + + const year = parseInt(unwrap_any($("#year").val())); + const month = parseInt(unwrap_any($("#month").val())); + const repeatCnt = parseInt(unwrap_any($("#repeat_cnt").val())); + + const seed = unwrap_any($("#seed").val()); + + return { + attackerGeneral: attackerGeneral, + attackerCity: attackerCity, + attackerNation: attackerNation, + + defenderGenerals: defenderGenerals, + defenderCity: defenderCity, + defenderNation: defenderNation, + + year: year, + month: month, + repeatCnt: repeatCnt, + + seed, + }; + }; + + const extendAllDataForDB = function (allData: BattleInfo): BattleInfo { + const defaultNation = { + nation: 0, + name: "재야", + capital: 0, + level: 0, + gold: 0, + rice: 2000, + type: "None", + tech: 0, + gennum: 200, + }; + + const defaultCity = { + nation: 0, + supply: 1, + name: "도시", + + pop: 500000, + agri: 10000, + comm: 10000, + secu: 10000, + def: 1000, + wall: 1000, + + trust: 100, + + pop_max: 600000, + agri_max: 12000, + comm_max: 12000, + secu_max: 10000, + def_max: 12000, + wall_max: 12000, + + dead: 0, + + state: 0, + + conflict: "{}", + }; + + const attackerNation = $.extend({}, defaultNation, allData.attackerNation); + attackerNation.nation = 1; + attackerNation.name = "출병국"; + + const attackerCity = $.extend({}, defaultCity, allData.attackerCity) as CityBasicInfo; + attackerCity.nation = 1; + attackerCity.city = 1; + + const attackerGeneral = extendGeneralInfoForDB(allData.attackerGeneral); + if (2 <= attackerGeneral.officer_level && attackerGeneral.officer_level <= 4) { + attackerGeneral.officer_city = 1; + } else { + attackerGeneral.officer_city = 0; + } + + const defenderNation = $.extend({}, defaultNation, allData.defenderNation); + defenderNation.nation = 2; + defenderNation.name = "수비국"; + + const defenderCity = $.extend({}, defaultCity, allData.defenderCity); + defenderCity.nation = 2; + defenderCity.city = 3; + defenderCity.wall_max = Math.floor((defenderCity.wall / 5) * 6); + defenderCity.def_max = Math.floor((defenderCity.def / 5) * 6); + + const defenderGenerals: GeneralInfo[] = []; + $.each(allData.defenderGenerals, function () { + const defenderGeneral = extendGeneralInfoForDB(this); + if (2 <= defenderGeneral.officer_level && defenderGeneral.officer_level <= 4) { + defenderGeneral.officer_city = 3; + } else { + defenderGeneral.officer_city = 0; + } + + defenderGenerals.push(defenderGeneral); + }); + + return $.extend({}, allData, { + attackerGeneral: attackerGeneral, + attackerCity: attackerCity, + attackerNation: attackerNation, + + defenderGenerals: defenderGenerals, + defenderCity: defenderCity, + defenderNation: defenderNation, + }); + }; + + const parseSkillCount = function (skills: Record) { + const result: string[] = []; + for (const [key, value] of Object.entries(skills)) { + result.push(`${key}(${toPretty(value)}회)`); + } + + if (result.length == 0) { + return "-"; + } + return result.join(", "); + }; + + const toPretty = function (number: number) { + if (isInteger(number)) { + number = Math.floor(number); + } else { + number = parseFloat(number.toFixed(2)); + } + return numberWithCommas(number); + }; + + const showBattleResult = function (result: BattleResult) { + $("#result_datetime").html(result.datetime); + $("#result_warcnt").html(toPretty(result.avgWar)); + $("#result_phase").html(toPretty(result.phase)); + $("#result_killed").html(toPretty(result.killed)); + if (result.minKilled != result.maxKilled) { + $("#result_maxKilled").html(toPretty(result.maxKilled)); + $("#result_minKilled").html(toPretty(result.minKilled)); + $("#result_varKilled").show(); + } else { + $("#result_varKilled").hide(); + } + $("#result_dead").html(toPretty(result.dead)); + if (result.minDead != result.maxDead) { + $("#result_maxDead").html(toPretty(result.maxDead)); + $("#result_minDead").html(toPretty(result.minDead)); + $("#result_varDead").show(); + } else { + $("#result_varDead").hide(); + } + + $("#result_attackerRice").html(toPretty(result.attackerRice)); + $("#result_defenderRice").html(toPretty(result.defenderRice)); + $("#result_attackerSkills").html(parseSkillCount(result.attackerSkills)); + + $(".result_defenderSkills").detach(); + + const $summary = $("#battle_result_summary"); + + for (const [idx, defenderSkills] of Object.entries(result.defendersSkills)) { + console.log(defenderSkills); + const $result = $(`수비자${parseInt(idx) + 1} 스킬`); + $result.find("td").html(parseSkillCount(defenderSkills)); + $summary.append($result); + } + + $("#generalBattleResultLog").html(result.lastWarLog.generalBattleResultLog); + $("#generalBattleDetailLog").html(result.lastWarLog.generalBattleDetailLog); + }; + + const beginBattle = function () { + const data = extendAllDataForDB(exportAllData()); + console.log(data); + $.ajax({ + type: "post", + url: "j_simulate_battle.php", + dataType: "json", + data: { + action: "battle", + query: JSON.stringify(data), + }, + }).then( + function (result) { + console.log(result); + if (!result.result) { + alert(result.reason); + return; } + showBattleResult(result); + }, + function () { + alert("전투 개시 실패!"); + } + ); + }; + const reorderDefender = function (defenderOrder: number[]) { + for (const generalNo of defenderOrder) { + if (!(generalNo in defenderNoList)) { + //음..? + alert(`${generalNo}이 수비자 리스트에 없습니다. 버그인 듯 합니다.`); return true; + } + + const $defenderObj = defenderNoList[generalNo]; + $defenderObj.detach(); + $defenderColumn.append($defenderObj); } + }; - const extendGeneralInfoForDB = function (generalData: GeneralInfo) { - - const dbVal = { - nation: (generalData.no) <= 1 ? 1 : 2, - city: (generalData.no) <= 1 ? 1 : 3, - turntime: '2018-08-26 12:00', - special: window.defaultSpecialDomestic, - leadership_exp: 0, - strength_exp: 0, - intel_exp: 0, - - gold: 10000, - - dedication: 0, - - recent_war: '2018-08-26 12:00', - experience: Math.pow(generalData.explevel, 2), - }; - - return $.extend({}, generalData, dbVal); - } - - const getGeneralFrame = function ($btn: JQuery) { - const $card = $btn.closest('.general_form'); - return $card; - } - - const getGeneralDetail = function ($btn: JQuery) { - const $card = getGeneralFrame($btn); - const $general = $card.find('.general_detail'); - return $general; - } - - const getGeneralNo = function ($btn: JQuery) { - return parseInt(getGeneralFrame($btn).data('general_no')); - } - - const setGeneralNo = function ($btn: JQuery, value: number) { - if (value == 1) { - //1번은 무조건 공격자임 - return false; + const requestReorderDefender = function () { + const data = extendAllDataForDB(exportAllData()); + console.log(data); + $.ajax({ + type: "post", + url: "j_simulate_battle.php", + dataType: "json", + data: { + action: "reorder", + query: JSON.stringify(data), + }, + }).then( + function (result) { + console.log(result); + if (!result.result) { + alert(result.reason); + return; } - if (value in defenderNoList) { - return false; - } - const $card = getGeneralFrame($btn); - $card.data('general_no', value); - defenderNoList[value] = $card; - return true; - } + reorderDefender(result.order); + }, + function () { + alert("재정렬 실패!"); + } + ); + }; - const generateNewGeneralNo = function () { - for (; ;) { - const newGeneralNo = Math.floor(Math.random() * (1 << 24)) + 2; - if (newGeneralNo in defenderNoList) { - continue; - } - return newGeneralNo; - } - } + let initGeneralList = false; - const deleteGeneralNo = function ($btn: JQuery) { - const $card = getGeneralFrame($btn); - $card.removeData('general_no'); - const generalNo = getGeneralNo($card); - delete defenderNoList[generalNo]; - } + $("#importFromDB").on("click", function () { + const generalID = $("#modalSelector").val(); + console.log(generalID); - const addDefender = function ($cardAfter?: JQuery) { - const $newCard = $('
'); + $.post({ + url: "j_export_simulator_object.php", + dataType: "json", + data: { + destGeneralID: generalID, + }, + }).then(function (data) { + if (!data.result) { + alert(data.reason); + return false; + } - if ($cardAfter === undefined) { - $defenderColumn.append($newCard); - } else { - $cardAfter.after($newCard); - } + const $modal = $("#importModal"); + const $card = $modal.data("target"); + importGeneralInfo($card, data.general); - $newCard.append($defenderHeaderForm.clone(true, true)); - $newCard.append($generalForm.clone(true, true)); + if (modalImport) { + modalImport.hide(); + } + }, errUnknown); + }); - //$newGeneral = getGeneralDetail($newCard); - setGeneralNo($newCard, generateNewGeneralNo()); + unwrap(document.querySelector("#importModal")).addEventListener("show.bs.modal", function () { + if (!initGeneralList) { + const $list = $("#modalSelector"); - return $newCard; - } - - const deleteDefender = function ($card: JQuery) { - deleteGeneralNo($card); - $card.detach(); - } - - const copyDefender = function ($card: JQuery) { - const $general = getGeneralDetail($card); - - const generalData = exportGeneralInfo($general); - const $newObj = addDefender($card); - importGeneralInfo(getGeneralDetail($newObj), generalData); - } - - const importBattleInfo = function (battleData: BattleInfo) { - - $('.form_load_battle_file').val(''); - console.log(battleData); - - const $attackerNation = $('.attacker_nation'); - const $defenderNation = $('.defender_nation'); - - const attackerGeneral = battleData.attackerGeneral; - const attackerCity = battleData.attackerCity; - const attackerNation = battleData.attackerNation; - - const defenderGenerals = battleData.defenderGenerals; - const defenderCity = battleData.defenderCity; - const defenderNation = battleData.defenderNation; - - const seed = battleData.seed; - - if(seed){ - $('#seed').val(seed); - } - - $('#year').val(battleData.year); - $('#month').val(battleData.month); - $('#repeat_cnt').val(battleData.repeatCnt); - - $('.delete-defender').trigger('click'); - - $attackerNation.find('.form_nation_type').val(attackerNation.type); - $attackerNation.find('.form_tech').val(Math.floor(attackerNation.tech / 1000)); - $attackerNation.find('.form_nation_level').val(attackerNation.level); - if (attackerNation.capital == 1) { - $attackerNation.find('.form_is_capital:first').trigger('click'); - } else { - $attackerNation.find('.form_is_capital:last').trigger('click'); - } - $attackerNation.find('.form_city_level').val(attackerCity.level); - - importGeneralInfo($('.attacker_form'), attackerGeneral); - - $defenderNation.find('.form_nation_type').val(defenderNation.type); - $defenderNation.find('.form_tech').val(Math.floor(defenderNation.tech / 1000)); - $defenderNation.find('.form_nation_level').val(defenderNation.level); - if (defenderNation.capital == 1) { - $defenderNation.find('.form_is_capital:first').trigger('click'); - } else { - $defenderNation.find('.form_is_capital:last').trigger('click'); - } - $defenderNation.find('.form_city_level').val(defenderCity.level); - $('#city_def').val(defenderCity.def); - $('#city_wall').val(defenderCity.wall); - - $.each(defenderGenerals, function (idx, defenderGeneral) { - const $card = addDefender(); - importGeneralInfo($card, defenderGeneral); + const addNation = function (generalList: GeneralInfo[], nationName: string, color: string) { + generalList.sort(function (lhs, rhs) { + if (lhs.npc != rhs.npc) { + return (lhs.npc ?? 0) - (rhs.npc ?? 0); + } + if (lhs.name < rhs.name) { + return -1; + } + if (lhs.name > rhs.name) { + return 1; + } + return 0; }); - } + const $optGroup = $(``); + $optGroup.css("background-color", color); + $optGroup.css("color", isBrightColor(color) ? "black" : "white"); - const exportAllData = function (): BattleInfo { - const $attackerNation = $('.attacker_nation'); - const $defenderNation = $('.defender_nation'); - - const attackerGeneral = exportGeneralInfo($('.attacker_form')); - - const attackerCity = { - level: parseInt($attackerNation.find('.form_city_level').val() as string), - }; - - const attackerNation = { - type: unwrap_any($attackerNation.find('.form_nation_type').val()), - tech: parseInt($attackerNation.find('.form_tech').val() as string) * 1000, - level: parseInt($attackerNation.find('.form_nation_level').val() as string), - capital: $attackerNation.find('.form_is_capital:checked').val() == '1' ? 1 : 2, + for (const general of generalList) { + const $item = $(``); + if (general.npc) { + $item.css("color", unwrap(getNPCColor(general.npc))); + } else { + $item.css("color", "white"); + } + $item.css("background-color", "black"); + $optGroup.append($item); + } + $list.append($optGroup); + }; + $.post({ + url: "j_get_basic_general_list.php", + dataType: "json", + data: { + req: 2, + }, + }).then(function (data: BasicGeneralListResponse | InvalidResponse) { + if (!data.result) { + alert(data.reason); + if (modalImport) { + modalImport.hide(); + } + return false; } - const defenderGenerals = $('.defender_form').map(function () { - return exportGeneralInfo($(this)); - }).toArray(); + const nations = data.nation; + const myNationID = data.nationID; - const defenderCity = { - def: parseInt($('#city_def').val() as string), - wall: parseInt($('#city_wall').val() as string), - level: parseInt($defenderNation.find('.form_city_level').val() as string), - }; + $list.empty(); + //자국 먼저 - const defenderNation = { - type: unwrap_any($defenderNation.find('.form_nation_type').val()), - tech: parseInt(unwrap_any($defenderNation.find('.form_tech').val())) * 1000, - level: parseInt(unwrap_any($defenderNation.find('.form_nation_level').val())), - capital: $defenderNation.find('.form_is_capital:checked').val() == '1' ? 3 : 4, - } - - const year = parseInt(unwrap_any($('#year').val())); - const month = parseInt(unwrap_any($('#month').val())); - const repeatCnt = parseInt(unwrap_any($('#repeat_cnt').val())); - - const seed = unwrap_any($('#seed').val()); - - return { - attackerGeneral: attackerGeneral, - attackerCity: attackerCity, - attackerNation: attackerNation, - - defenderGenerals: defenderGenerals, - defenderCity: defenderCity, - defenderNation: defenderNation, - - year: year, - month: month, - repeatCnt: repeatCnt, - - seed, - }; - } - - const extendAllDataForDB = function (allData: BattleInfo): BattleInfo { - const defaultNation = { + if (0 in data.list) { + nations[0] = { nation: 0, - name: '재야', - capital: 0, - level: 0, - gold: 0, - rice: 2000, - type: 'None', - tech: 0, - gennum: 200, - }; - - const defaultCity = { - nation: 0, - supply: 1, - name: '도시', - - pop: 500000, - agri: 10000, - comm: 10000, - secu: 10000, - def: 1000, - wall: 1000, - - trust: 100, - - pop_max: 600000, - agri_max: 12000, - comm_max: 12000, - secu_max: 10000, - def_max: 12000, - wall_max: 12000, - - dead: 0, - - state: 0, - - conflict: '{}', - }; - - const attackerNation = $.extend({}, defaultNation, allData.attackerNation); - attackerNation.nation = 1; - attackerNation.name = '출병국'; - - const attackerCity = $.extend({}, defaultCity, allData.attackerCity) as CityBasicInfo; - attackerCity.nation = 1; - attackerCity.city = 1; - - const attackerGeneral = extendGeneralInfoForDB(allData.attackerGeneral); - if (2 <= attackerGeneral.officer_level && attackerGeneral.officer_level <= 4) { - attackerGeneral.officer_city = 1; - } else { - attackerGeneral.officer_city = 0; + name: "재야", + color: "#000000", + }; } - const defenderNation = $.extend({}, defaultNation, allData.defenderNation); - defenderNation.nation = 2; - defenderNation.name = '수비국'; + addNation( + combineArray(data.list[myNationID], data.column) as GeneralInfo[], + nations[myNationID].name, + nations[myNationID].color + ); - const defenderCity = $.extend({}, defaultCity, allData.defenderCity); - defenderCity.nation = 2; - defenderCity.city = 3; - defenderCity.wall_max = Math.floor(defenderCity.wall / 5 * 6); - defenderCity.def_max = Math.floor(defenderCity.def / 5 * 6); - - const defenderGenerals: GeneralInfo[] = []; - $.each(allData.defenderGenerals, function () { - const defenderGeneral = extendGeneralInfoForDB(this); - if (2 <= defenderGeneral.officer_level && defenderGeneral.officer_level <= 4) { - defenderGeneral.officer_city = 3; - } else { - defenderGeneral.officer_city = 0; - } - - defenderGenerals.push(defenderGeneral); - }); - - - return $.extend({}, allData, { - attackerGeneral: attackerGeneral, - attackerCity: attackerCity, - attackerNation: attackerNation, - - defenderGenerals: defenderGenerals, - defenderCity: defenderCity, - defenderNation: defenderNation, - }); + for (const nationID of Object.keys(data.list)) { + if (parseInt(nationID) == myNationID) { + continue; + } + addNation( + combineArray(data.list[nationID], data.column) as GeneralInfo[], + nations[nationID].name, + nations[nationID].color + ); + } + initGeneralList = true; + }, errUnknown); } + }); - const parseSkillCount = function (skills: Record) { - const result: string[] = []; - for (const [key, value] of Object.entries(skills)) { - result.push(`${key}(${toPretty(value)}회)`); - } + initBasicEvent(); + $attackerCard.append($generalForm.clone(true, true)); + addDefender(); - if (result.length == 0) { - return '-'; - } - return result.join(', '); - } + $(".btn-begin_battle").on("click", function () { + beginBattle(); + }); - const toPretty = function (number: number) { - if (isInteger(number)) { - number = Math.floor(number); - } else { - number = parseFloat(number.toFixed(2)); - } - return numberWithCommas(number); - } - - const showBattleResult = function (result: BattleResult) { - $('#result_datetime').html(result.datetime); - $('#result_warcnt').html(toPretty(result.avgWar)); - $('#result_phase').html(toPretty(result.phase)); - $('#result_killed').html(toPretty(result.killed)); - if (result.minKilled != result.maxKilled) { - $('#result_maxKilled').html(toPretty(result.maxKilled)); - $('#result_minKilled').html(toPretty(result.minKilled)); - $('#result_varKilled').show(); - } else { - $('#result_varKilled').hide(); - } - $('#result_dead').html(toPretty(result.dead)); - if (result.minDead != result.maxDead) { - $('#result_maxDead').html(toPretty(result.maxDead)); - $('#result_minDead').html(toPretty(result.minDead)); - $('#result_varDead').show(); - } else { - $('#result_varDead').hide(); - } - - $('#result_attackerRice').html(toPretty(result.attackerRice)); - $('#result_defenderRice').html(toPretty(result.defenderRice)); - $('#result_attackerSkills').html(parseSkillCount(result.attackerSkills)); - - $('.result_defenderSkills').detach(); - - const $summary = $('#battle_result_summary'); - - for (const [idx, defenderSkills] of Object.entries(result.defendersSkills)) { - console.log(defenderSkills); - const $result = $(`수비자${parseInt(idx) + 1} 스킬`); - $result.find('td').html(parseSkillCount(defenderSkills)); - $summary.append($result); - } - - $('#generalBattleResultLog').html(result.lastWarLog.generalBattleResultLog); - $('#generalBattleDetailLog').html(result.lastWarLog.generalBattleDetailLog); - - } - - const beginBattle = function () { - const data = extendAllDataForDB(exportAllData()); - console.log(data); - $.ajax({ - type: 'post', - url: 'j_simulate_battle.php', - dataType: 'json', - data: { - action: 'battle', - query: JSON.stringify(data), - } - }).then(function (result) { - console.log(result); - if (!result.result) { - alert(result.reason); - return; - } - showBattleResult(result); - - }, function () { - alert('전투 개시 실패!'); - }); - } - - - const reorderDefender = function (defenderOrder: number[]) { - for (const generalNo of defenderOrder) { - - if (!(generalNo in defenderNoList)) { - //음..? - alert(`${generalNo}이 수비자 리스트에 없습니다. 버그인 듯 합니다.`); - return true; - } - - const $defenderObj = defenderNoList[generalNo]; - $defenderObj.detach(); - $defenderColumn.append($defenderObj); - } - } - - const requestReorderDefender = function () { - const data = extendAllDataForDB(exportAllData()); - console.log(data); - $.ajax({ - type: 'post', - url: 'j_simulate_battle.php', - dataType: 'json', - data: { - action: 'reorder', - query: JSON.stringify(data), - } - }).then(function (result) { - console.log(result); - if (!result.result) { - alert(result.reason); - return; - } - reorderDefender(result.order); - - }, function () { - alert('재정렬 실패!'); - }); - } - - let initGeneralList = false; - - $('#importFromDB').on('click', function () { - const generalID = $('#modalSelector').val(); - console.log(generalID); - - - $.post({ - url: 'j_export_simulator_object.php', - dataType: 'json', - data: { - destGeneralID: generalID - } - }).then(function (data) { - - if (!data.result) { - alert(data.reason); - return false; - } - - const $modal = $('#importModal'); - const $card = $modal.data('target'); - importGeneralInfo($card, data.general); - - if(modalImport){ - modalImport.hide(); - } - }, errUnknown); - - - }); - - unwrap(document.querySelector('#importModal')).addEventListener('show.bs.modal', function () { - if (!initGeneralList) { - const $list = $('#modalSelector'); - - const addNation = function (generalList: GeneralInfo[], nationName: string, color: string) { - - generalList.sort(function (lhs, rhs) { - if (lhs.npc != rhs.npc) { - return (lhs.npc ?? 0) - (rhs.npc ?? 0); - } - if (lhs.name < rhs.name) { - return -1; - } - if (lhs.name > rhs.name) { - return 1; - } - return 0; - }) - const $optGroup = $(``); - $optGroup.css('background-color', color); - $optGroup.css('color', isBrightColor(color) ? 'black' : 'white'); - - for (const general of generalList) { - const $item = $(``); - if (general.npc) { - $item.css('color', unwrap(getNPCColor(general.npc))); - } else { - $item.css('color', 'white'); - } - $item.css('background-color', 'black'); - $optGroup.append($item); - } - $list.append($optGroup); - } - $.post({ - url: 'j_get_basic_general_list.php', - dataType: 'json', - data: { - req: 2, - } - }).then(function (data: BasicGeneralListResponse | InvalidResponse) { - if (!data.result) { - alert(data.reason); - if(modalImport){ - modalImport.hide(); - } - return false; - } - - const nations = data.nation; - const myNationID = data.nationID; - - $list.empty(); - //자국 먼저 - - if (0 in data.list) { - nations[0] = { - nation: 0, - name: '재야', - color: '#000000' - }; - } - - - - addNation(combineArray(data.list[myNationID], data.column) as GeneralInfo[], nations[myNationID].name, nations[myNationID].color); - - for (const nationID of Object.keys(data.list)) { - if (parseInt(nationID) == myNationID) { - continue; - } - addNation(combineArray(data.list[nationID], data.column) as GeneralInfo[], nations[nationID].name, nations[nationID].color); - } - initGeneralList = true; - }, errUnknown); - } - - }); - - initBasicEvent(); - $attackerCard.append($generalForm.clone(true, true)); - addDefender(); - - $('.btn-begin_battle').on('click', function () { - beginBattle(); - }); - - $('.btn-reorder_defender').on('click', function () { - requestReorderDefender(); - }) -}); \ No newline at end of file + $(".btn-reorder_defender").on("click", function () { + requestReorderDefender(); + }); +});