diff --git a/hwe/sammo/API/Global/GetConst.php b/hwe/sammo/API/Global/GetConst.php index be599f33..fb14c627 100644 --- a/hwe/sammo/API/Global/GetConst.php +++ b/hwe/sammo/API/Global/GetConst.php @@ -184,7 +184,7 @@ class GetConst extends \sammo\BaseAPI } if (is_string($target)) { - return $this->extractObjClassInfo($target, $callerFunction); + return [$target => $this->extractObjClassInfo($target, $callerFunction)]; } if (!is_array($target)) { diff --git a/hwe/ts/GameConstStore.ts b/hwe/ts/GameConstStore.ts new file mode 100644 index 00000000..a8669011 --- /dev/null +++ b/hwe/ts/GameConstStore.ts @@ -0,0 +1,49 @@ +import { SammoAPI } from '@/SammoAPI'; +import type { GetConstResponse } from './defs/API/Global'; +import type { CityID, CrewTypeID, GameCityDefault, GameConstType, GameUnitType, GameIActionCategory, GameIActionKey, GameIActionInfo } from './defs/GameObj'; + +export class GameConstStore { + public readonly gameConst: GameConstType; + public readonly gameUnitConst: Record; + public readonly cityConst: Record; + public readonly cityConstMap: { + region: Record; + level: Record; //defs.CityLevelText + }; + public readonly iActionInfo: Record< + GameIActionCategory, + Record< + GameIActionKey, + GameIActionInfo + > + >; + public readonly iActionKeyMap: Record; + + constructor(response: GetConstResponse) { + const data = response.data; + this.gameConst = Object.freeze(data.gameConst); + this.gameUnitConst = Object.freeze(data.gameUnitConst); + this.cityConst = Object.freeze(data.cityConst); + this.cityConstMap = Object.freeze(data.cityConstMap); + this.iActionInfo = Object.freeze(data.iActionInfo); + this.iActionKeyMap = Object.freeze(data.iActionKeyMap); + } +} + +let gameConstStore: GameConstStore | undefined = undefined; + +export async function getGameConstStore(): Promise { + //TODO: LocalStorage Cache 조합도 생각해보기. + if (gameConstStore !== undefined) { + return gameConstStore; + } + try { + const result = await SammoAPI.Global.GetConst(); + gameConstStore = new GameConstStore(result); + } + catch (e: unknown) { + console.error(`FATAL!: GameConst를 가져오지 못함: ${e}`); + throw e; + } + return gameConstStore; +} \ No newline at end of file diff --git a/hwe/ts/SammoAPI.ts b/hwe/ts/SammoAPI.ts index 7baaaac6..ebad9a55 100644 --- a/hwe/ts/SammoAPI.ts +++ b/hwe/ts/SammoAPI.ts @@ -12,6 +12,7 @@ import type { inheritBuffType } from "./defs/API/InheritAction"; import type { SetBlockWarResponse } from "./defs/API/Nation"; import type { UploadImageResponse } from "./defs/API/Misc"; import type { JoinArgs } from "./defs/API/General"; +import type { GetConstResponse } from "./defs/API/Global"; const apiRealPath = { Betting: { @@ -47,6 +48,9 @@ const apiRealPath = { General: { Join: POST as APICallT, }, + Global: { + GetConst: GET as APICallT, + }, InheritAction: { BuyHiddenBuff: PUT as APICallT<{ type: inheritBuffType, diff --git a/hwe/ts/defs/API/Global.ts b/hwe/ts/defs/API/Global.ts new file mode 100644 index 00000000..d2477d0f --- /dev/null +++ b/hwe/ts/defs/API/Global.ts @@ -0,0 +1,36 @@ +import type { CityID, CrewTypeID, GameCityDefault, GameConstType, GameUnitType, GameIActionKey, GameIActionCategory, GameIActionInfo } from "@/defs/GameObj"; + +export interface GetConstResponse { + result: true; + cacheKey: string; + data: { + gameConst: GameConstType; + gameUnitConst: Record; + cityConst: Record; + cityConstMap: { + region: Record; + level: Record; //defs.CityLevelText + }; + iActionInfo: Record< + GameIActionCategory, + Record< + GameIActionKey, + GameIActionInfo + > + >; + iActionKeyMap: { + availableNationType: "nationType"; + neutralNationType: "nationType"; + defaultSpecialDomestic: "specialDomestic"; + availableSpecialDomestic: "specialDomestic"; + optionalSpecialDomestic: "specialDomestic"; + defaultSpecialWar: "specialWar"; + availableSpecialWar: "specialWar"; + optionalSpecialWar: "specialWar"; + neutralPersonality: "personality"; + availablePersonality: "personality"; + optionalPersonality: "personality"; + allItems: "item"; + }; + }; +} \ No newline at end of file diff --git a/hwe/ts/defs/GameObj.ts b/hwe/ts/defs/GameObj.ts new file mode 100644 index 00000000..5da99a84 --- /dev/null +++ b/hwe/ts/defs/GameObj.ts @@ -0,0 +1,212 @@ +import type { CityLevel, ItemTypeKey } from "."; + +type CSSRGBColor = string; + +export type GameObjClassKey = string; +export type GameIActionKey = GameObjClassKey; + +type SpecialDomesticKey = GameIActionKey; +type SpecialWarKey = GameIActionKey; +type GameItemKey = GameIActionKey; +type MapTypeKey = string; +type UnitSetKey = string; +type RawHTMLString = string; +type NationTypeKey = GameIActionKey; +type GamePersonalityKey = GameIActionKey; +type GeneralCommandName = GameObjClassKey; +type ChiefCommandName = GameObjClassKey; + +/** GameConst.php */ +export type GameConstType = { + title: string; + banner: RawHTMLString; + mapName: MapTypeKey; + unitSet: UnitSetKey; + develrate: number; + upgradeLimit: number; + dexLimit: number; + defaultAtmosLow: number; + defaultTrainLow: number; + defaultAtmosHigh: number; + defaultTrainHigh: number; + maxAtmosByCommand: number; + maxTrainByCommand: number; + maxAtmosByWar: number; + maxTrainByWar: number; + trainDelta: number; + atmosDelta: number; + atmosSideEffectByTraining: number; + trainSideEffectByAtmosTurn: number; + sabotageDefaultProb: number; + sabotageProbCoefByStat: number; + sabotageDamageMin: number; + sabotageDamageMax: number; + basecolor: CSSRGBColor; + basecolor2: CSSRGBColor; + basecolor3: CSSRGBColor; + basecolor4: CSSRGBColor; + armperphase: number; + basegold: number; + baserice: number; + minNationalGold: number; + minNationalRice: number; + exchangeFee: number; + adultAge: number; + minPushHallAge: number; + maxDedLevel: number; + maxTechLevel: number; + maxBetrayCnt: number; + + basePopIncreaseAmount: number; + expandCityPopIncreaseAmount: number; + expandCityDevelIncreaseAmount: number; + expandCityWallIncreaseAmount: number; + expandCityDefaultCost: number; + expandCityCostCoef: number; + minAvailableRecruitPop: number; + initialNationGenLimitForRandInit: number; + initialNationGenLimit: number; + + defaultMaxGeneral: number; + defaultMaxNation: number; + defaultMaxGenius: number; + defaultStartYear: number; + + joinRuinedNPCProp: number; + + defaultGold: number; + defaultRice: number; + + coefAidAmount: number; + + maxResourceActionAmount: number; + resourceActionAmountGuide: number[]; + + generalMinimumGold: number; + generalMinimumRice: number; + + maxTurn: number; + maxChiefTurn: number; + + statGradeLevel: number; + + openingPartYear: number; + joinActionLimit: number; + + bornMinStatBonus: number; + bornMaxStatBonus: number; + + availableNationType: NationTypeKey[]; + neutralNationType: NationTypeKey; + + defaultSpecialDomestic: SpecialDomesticKey; + availableSpecialDomestic: SpecialDomesticKey[]; + optionalSpecialDomestic: SpecialDomesticKey[]; + + defaultSpecialWar: SpecialWarKey; + availableSpecialWar: SpecialWarKey[]; + optionalSpecialWar: SpecialWarKey[]; + + neutralPersonality: GamePersonalityKey; + availablePersonality: GamePersonalityKey[]; + optionalPersonality: GamePersonalityKey[]; + + maxUniqueItemLimit: [number, number][]; + + maxAvailableWarSettingCnt: number; + incAvailableWarSettingCnt: number; + + minMonthToAllowInheritItem: number; + inheritBornSpecialPoint: number; + inheritBornTurntimePoint: number; + inheritBornCityPoint: number; + inheritBornStatPoint: number; + inheritItemUniqueMinPoint: number; + inheritItemRandomPoint: number; + inheritBuffPoints: number[]; + inheritSpecificSpecialPoint: number; + inheritResetAttrPointBase: number[]; + + allItems: Record>; + + availableGeneralCommand: Record; + availableChiefCommand: Record; + + retirementYear: number; + + targetGeneralPool: GameObjClassKey; + generalPoolAllowOption: string[]; + + randGenFirstName: string[]; + randGenMiddleName: string[]; + randGenLastName: string[]; + + npcBanMessageProb: number; + npcSeizureMessageProb: number; + npcMessageFreqByDay: number; + + /** + * Scenario::getGameConf + */ + + defaultStatTotal: number; + defaultStatMin: number; + defaultStatMax: number; + defaultStatNPCTotal: number; + defaultStatNPCMax: number; + defaultStatNPCMin: number; + chiefStatMin: number; + +}; + +export type CrewTypeID = number; +export type ArmTypeID = 0 | 1 | 2 | 3 | 4 | 5; + +export type MapRegionID = number; +export type CityID = number; + +export type GameUnitType = { + id: CrewTypeID; + armType: ArmTypeID; + name: string; + attack: number; + defence: number; + speed: number; + avoid: number; + magicCoef: number; + cost: number; + rice: number; + reqTech: number; + reqCities: CityID[] | null; + reqRegions: MapRegionID[] | null; + reqYear: number; + attackCoef: Record | null | []; + defenceCoef: Record | null | []; + info: string | string[]; + initSkillTrigger: GameObjClassKey[] | null; + phaseSkillTrigger: GameObjClassKey[] | null; +}; + +export type GameCityDefault = { + id: CityID; + name: string; + level: CityLevel; + population: number; + agriculture: number; + commerce: number; + security: number; + defence: number; + wall: number; + region: number; + posX: number; + posY: number; + path: Record; +}; + +export type GameIActionCategory = "nationType" | "specialDomestic" | "specialWar" | "personality" | "item"; + +export type GameIActionInfo = { + value: string; + name: string; + info?: string | null; +} \ No newline at end of file