diff --git a/@sammo/game_logic/src/GeneralSpecial/BaseSpecial.ts b/@sammo/game_logic/src/GeneralSpecial/BaseSpecial.ts new file mode 100644 index 0000000..7da9fb3 --- /dev/null +++ b/@sammo/game_logic/src/GeneralSpecial/BaseSpecial.ts @@ -0,0 +1,19 @@ +import type { IAction } from "../IAction.js"; +import type { SpecialReqType, WeightType } from "./defs.js"; + +export abstract class BaseSpecial implements IAction { + public abstract readonly name: string; + + static readonly selectWeight: WeightType = { + type: "normal", + weight: 1, + } + + static readonly type: SpecialReqType[] = []; + + getName(): string { + return this.name; + } + + abstract getInfo(): string[]|string; +} \ No newline at end of file diff --git a/@sammo/game_logic/src/GeneralSpecial/SpecialWar/che_필살.ts b/@sammo/game_logic/src/GeneralSpecial/SpecialWar/che_필살.ts new file mode 100644 index 0000000..50cfe59 --- /dev/null +++ b/@sammo/game_logic/src/GeneralSpecial/SpecialWar/che_필살.ts @@ -0,0 +1,47 @@ +import type { General } from "../../General.js"; +import type { BattlePhaseTrigger, CalcStat, CalcStatRange } from "../../IActionMethod.js"; +import { WarUnitTriggerCaller } from "../../TriggerCaller/WarUnitTriggerCaller.js"; +import type { WarUnit } from "../../WarUnit.js"; +import { che_필살강화_회피불가 } from "../../WarUnitTrigger/che_필살강화_회피불가.js"; +import { BaseSpecial } from "../BaseSpecial.js"; +import type { SpecialReqType, WeightNormal } from "../defs.js"; + +export class che_필살 extends BaseSpecial implements CalcStat, CalcStatRange, BattlePhaseTrigger { + public readonly name = "필살"; + + static override readonly selectWeight: WeightNormal = { + type: "normal", + weight: 1, + } + static override type: SpecialReqType[] = [ + 'statLeadership', + 'statStrength', + 'statIntel', + ]; + + getInfo() { + return "[전투] 필살 확률 +30%p, 필살 발동시 대상 회피 불가, 필살 계수 향상"; + } + + onCalcStat(general: General, statName: string, value: number, aux?: unknown[] | undefined): number { + if (statName == 'warCriticalRatio') { + return value + 0.3; + } + return value; + } + + onCalcStatRange(general: General, statName: string, value: [number, number], aux?: unknown[] | undefined): [number, number] { + if (statName === 'criticalDamageRange'){ + const [rangeMin, rangeMax] = value; + return [(rangeMin + rangeMax) / 2, rangeMax]; + } + + return value; + } + + getBattlePhaseSkillTriggerList(unit: WarUnit): WarUnitTriggerCaller | undefined { + return new WarUnitTriggerCaller( + new che_필살강화_회피불가(unit), + ); + } +} \ No newline at end of file diff --git a/@sammo/game_logic/src/GeneralSpecial/SpecilityHelper.ts b/@sammo/game_logic/src/GeneralSpecial/SpecilityHelper.ts new file mode 100644 index 0000000..a304704 --- /dev/null +++ b/@sammo/game_logic/src/GeneralSpecial/SpecilityHelper.ts @@ -0,0 +1,6 @@ + + +class SpecialityHelper { +} + +export const specialityHelper = new SpecialityHelper(); \ No newline at end of file diff --git a/@sammo/game_logic/src/GeneralSpecial/defs.ts b/@sammo/game_logic/src/GeneralSpecial/defs.ts new file mode 100644 index 0000000..da14733 --- /dev/null +++ b/@sammo/game_logic/src/GeneralSpecial/defs.ts @@ -0,0 +1,30 @@ + +export type SpecialReqType = + "statLeadership" | + "statStrength" | + "statIntel" | + + "armyFootMan" | + "armyArcher" | + "armyCavalry" | + "armyWizard" | + "armySiege" | + + "reqDexterity" | + + "statNotLeadership" | + "statNotStrength" | + "statNotIntel" + ; + +export type WeightNormal = { + type: "normal"; + weight: number; // 1을 기준으로 한 가중치 곱 +}; + +export type WeightPercent = { + type: "percent"; + weight: number; // 1이면 100% +}; + +export type WeightType = WeightNormal | WeightPercent; \ No newline at end of file diff --git a/@sammo/game_logic/src/GeneralSpecial/index.ts b/@sammo/game_logic/src/GeneralSpecial/index.ts new file mode 100644 index 0000000..367d176 --- /dev/null +++ b/@sammo/game_logic/src/GeneralSpecial/index.ts @@ -0,0 +1,8 @@ +export { BaseSpecial } from "./BaseSpecial.js"; + +import { che_필살 } from "./SpecialWar/che_필살.js"; + + +export const SpecialWar = { + che_필살 +} \ No newline at end of file diff --git a/@sammo/game_logic/src/IAction.ts b/@sammo/game_logic/src/IAction.ts index 7e36c3d..f7ccaf0 100644 --- a/@sammo/game_logic/src/IAction.ts +++ b/@sammo/game_logic/src/IAction.ts @@ -1,25 +1,23 @@ -import type { RandUtil } from "@sammo/crypto"; -import type { General } from "./General.js"; -import type { GeneralTriggerCaller } from "./TriggerCaller/GeneralTriggerCaller.js"; -import type { WarUnitTriggerCaller } from "./TriggerCaller/WarUnitTriggerCaller.js"; -import type { WarUnit } from "./WarUnit.js"; +import type * as IMethod from "./IActionMethod.js"; +export type * as IMethod from "./IActionMethod.js"; + +export interface IActionMethod extends + IMethod.TurnExecuteTriggerList, + IMethod.CalcDomestic, + IMethod.CalcStat, + IMethod.CalcStatRange, + IMethod.CalcOpposeStat, + IMethod.CalcStrategic, + IMethod.CalcIncome, + IMethod.WarPowerMultiplier, + IMethod.BattleInitTrigger, + IMethod.BattlePhaseTrigger, + IMethod.ArbitraryAction { +} + +export interface IAction extends Partial { + readonly name: string; -export interface IAction { getName(): string; - getInfo(): string; - - getPreTurnExecuteTriggerList(general: General):GeneralTriggerCaller | undefined; - //TODO: turnType, varType이 string이면 안됨. enum에 가까워야함! - onCalcDomestic(turnType: string, varType: string, value: number, aux?: unknown[]): number; - - onCalcStat(general: General, statName: string, value: number, aux?: unknown[]): number; - onCalcOpposeStat(general: General, statName: string, value: number, aux?: unknown[]): number; - onCalcStrategic(turnType: string, varType: string, value: number): number; - onCalcNationalIncome(type: string, value: number): number; - - getWarPowerMultiplier(unit: WarUnit): [number, number]; - getBattleInitSkillTriggerList(unit: WarUnit): WarUnitTriggerCaller | undefined; - getBattlePhaseSkillTriggerList(unit: WarUnit): WarUnitTriggerCaller | undefined; - - onArbitraryAction(general: General, rng: RandUtil, actionType: string, phase?: string, aux?: unknown[]): null | string[]; + getInfo(): string[] | string; } \ No newline at end of file diff --git a/@sammo/game_logic/src/IActionMethod.ts b/@sammo/game_logic/src/IActionMethod.ts new file mode 100644 index 0000000..629ac3b --- /dev/null +++ b/@sammo/game_logic/src/IActionMethod.ts @@ -0,0 +1,62 @@ +import type { RandUtil } from "@sammo/crypto"; +import type { WarUnitTriggerCaller } from "./TriggerCaller/WarUnitTriggerCaller.js"; +import type { GeneralTriggerCaller } from "./TriggerCaller/GeneralTriggerCaller.js"; +import type { General } from "./General.js"; +import type { WarUnit } from "./WarUnit.js"; + +//TODO: turnType, varType이 string이면 안됨. enum에 가까워야함! +type onCalcDomesticFunc = (turnType: string, varType: string, value: number, aux?: unknown[]) => number; + +type onCalcStatFunc = (general: General, statName: string, value: number, aux?: unknown[]) => number; +type onCalcStatRangeFunc = (general: General, statName: string, value: [number, number], aux?: unknown[]) => [number, number]; +type onCalcStrategicFunc = (turnType: string, varType: string, value: number) => number; +type onCalcIncomeFunc = (type: string, value: number) => number; + +type getWarPowerMultiplierFunc = (unit: WarUnit) => [number, number]; +type getWarUnitTriggerListFunc = (unit: WarUnit) => WarUnitTriggerCaller | undefined; + +type onArbitraryActionFunc = (general: General, rng: RandUtil, actionType: string, phase?: string, aux?: unknown[]) => null | string[]; + +export interface TurnExecuteTriggerList { + getPreTurnExecuteTriggerList(general: General): GeneralTriggerCaller | undefined; +} + +export interface CalcDomestic { + onCalcDomestic: onCalcDomesticFunc; +} + +export interface CalcStat { + onCalcStat: onCalcStatFunc; +} + +export interface CalcStatRange { + onCalcStatRange: onCalcStatRangeFunc; +} + +export interface CalcOpposeStat { + onCalcOpposeStat: onCalcStatFunc; +} + +export interface CalcStrategic { + onCalcStrategic: onCalcStrategicFunc; +} + +export interface CalcIncome { + onCalcNationalIncome: onCalcIncomeFunc; +} + +export interface WarPowerMultiplier { + getWarPowerMultiplier: getWarPowerMultiplierFunc; +} + +export interface BattleInitTrigger { + getBatteInitSkillTriggerList: getWarUnitTriggerListFunc; +} + +export interface BattlePhaseTrigger { + getBattlePhaseSkillTriggerList: getWarUnitTriggerListFunc; +} + +export interface ArbitraryAction { + onArbitraryAction: onArbitraryActionFunc; +} \ No newline at end of file diff --git a/@sammo/game_logic/src/Trigger/BaseWarUnitTrigger.ts b/@sammo/game_logic/src/Trigger/BaseWarUnitTrigger.ts index f673ee7..079b307 100644 --- a/@sammo/game_logic/src/Trigger/BaseWarUnitTrigger.ts +++ b/@sammo/game_logic/src/Trigger/BaseWarUnitTrigger.ts @@ -12,11 +12,11 @@ export const RaiseType = { } as const; export abstract class BaseWarUnitTrigger extends ObjectTrigger { - protected priority = PRIORITY.BODY; + protected override priority: number = PRIORITY.BODY; constructor( protected object: WarUnit, - protected raiseType: number + protected raiseType: number = RaiseType.None, ) { super(); } diff --git a/@sammo/game_logic/src/TriggerCaller/WarUnitTriggerCaller.ts b/@sammo/game_logic/src/TriggerCaller/WarUnitTriggerCaller.ts index 9370be2..8ffbb3e 100644 --- a/@sammo/game_logic/src/TriggerCaller/WarUnitTriggerCaller.ts +++ b/@sammo/game_logic/src/TriggerCaller/WarUnitTriggerCaller.ts @@ -1,9 +1,9 @@ -import { BaseGeneralTrigger } from "../Trigger/BaseGeneralTrigger.js"; +import { BaseWarUnitTrigger } from "../Trigger/BaseWarUnitTrigger.js"; import type { ObjectTrigger } from "../Trigger/ObjectTrigger.js"; import { TriggerCaller } from "./TriggerCaller.js"; -export class WarUnitTriggerCaller extends TriggerCaller { +export class WarUnitTriggerCaller extends TriggerCaller { checkValidTrigger(trigger: ObjectTrigger): boolean { - return trigger instanceof BaseGeneralTrigger; + return trigger instanceof BaseWarUnitTrigger; } } \ No newline at end of file diff --git a/@sammo/game_logic/src/WarUnit.ts b/@sammo/game_logic/src/WarUnit.ts index ae50aa8..faea83a 100644 --- a/@sammo/game_logic/src/WarUnit.ts +++ b/@sammo/game_logic/src/WarUnit.ts @@ -3,5 +3,11 @@ export class WarUnitEnv { } export abstract class WarUnit{ + hasActivatedSkill(skillName: string): boolean { + throw new Error("Method not implemented."); + } + activateSkill(skillName: string): void { + throw new Error("Method not implemented."); + } } \ No newline at end of file diff --git a/@sammo/game_logic/src/WarUnitTrigger/che_필살강화_회피불가.ts b/@sammo/game_logic/src/WarUnitTrigger/che_필살강화_회피불가.ts new file mode 100644 index 0000000..23f5086 --- /dev/null +++ b/@sammo/game_logic/src/WarUnitTrigger/che_필살강화_회피불가.ts @@ -0,0 +1,17 @@ +import type { RandUtil } from "@sammo/crypto"; +import { BaseWarUnitTrigger } from "../Trigger/BaseWarUnitTrigger.js"; +import type { WarUnit, WarUnitEnv } from "../WarUnit.js"; +import { PRIORITY } from "../Trigger/ObjectTrigger.js"; + +export class che_필살강화_회피불가 extends BaseWarUnitTrigger { + protected override priority = PRIORITY.PRE + 150; + + actionWar(self: WarUnit, oppose: WarUnit, selfEnv: WarUnitEnv, opposeEnv: WarUnitEnv, rng: RandUtil): boolean { + if(!self.hasActivatedSkill("필살")){ + return true; + } + + oppose.activateSkill("회피불가"); + return true; + } +} \ No newline at end of file