game_logic 정의
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sammo/api_def": "workspace:^",
|
||||
"@sammo/crypto": "workspace:^",
|
||||
"@sammo/server_util": "workspace:^",
|
||||
"@sammo/util": "workspace:^",
|
||||
"@strpc/express": "workspace:^",
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export class GameEnv{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export class General {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
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";
|
||||
|
||||
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[];
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import type { General } from "../General.js";
|
||||
import { ObjectTrigger } from "./ObjectTrigger.js";
|
||||
|
||||
export abstract class BaseGeneralTrigger extends ObjectTrigger<General> {
|
||||
constructor(
|
||||
protected object: General,
|
||||
protected priority: number
|
||||
) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import type { RandUtil } from "@sammo/crypto";
|
||||
import type { WarUnit, WarUnitEnv } from "../WarUnit.js";
|
||||
import { ObjectTrigger, PRIORITY } from "./ObjectTrigger.js";
|
||||
import type { GameEnv } from "../GameEnv.js";
|
||||
import { NotYetImplemented } from "@sammo/util";
|
||||
|
||||
export const RaiseType = {
|
||||
None: 0,
|
||||
Item: 1,
|
||||
ConsumableItem: 3,
|
||||
DedupTypeBase: 1024,
|
||||
} as const;
|
||||
|
||||
export abstract class BaseWarUnitTrigger extends ObjectTrigger<WarUnit> {
|
||||
protected priority = PRIORITY.BODY;
|
||||
|
||||
constructor(
|
||||
protected object: WarUnit,
|
||||
protected raiseType: number
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
override getUniqueID(): string {
|
||||
const priority = this.getPriority();
|
||||
const name = this.constructor.name;
|
||||
const unitName = this.object?.constructor.name ?? "undefined";
|
||||
|
||||
return `${priority}:${name}:${unitName}`;
|
||||
}
|
||||
|
||||
action(rng: RandUtil, env: GameEnv, arg: unknown[]): void {
|
||||
throw new NotYetImplemented();
|
||||
console.log(rng, env, arg);
|
||||
}
|
||||
|
||||
abstract actionWar(self: WarUnit, oppose: WarUnit, selfEnv: WarUnitEnv, opposeEnv: WarUnitEnv, rng: RandUtil): boolean;
|
||||
|
||||
processConsumableItem(): boolean {
|
||||
throw new NotYetImplemented();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import type { RandUtil } from "@sammo/crypto";
|
||||
import type { GameEnv } from "../GameEnv.js";
|
||||
|
||||
export const PRIORITY = {
|
||||
MIN: 0,
|
||||
BEGIN: 10000,
|
||||
PRE: 20000,
|
||||
BODY: 30000,
|
||||
POST: 40000,
|
||||
FINAL: 50000,
|
||||
} as const;
|
||||
|
||||
export abstract class ObjectTrigger<T extends object> {
|
||||
protected abstract priority: number;
|
||||
protected abstract object?: T;
|
||||
|
||||
getPriority(): number {
|
||||
return this.priority;
|
||||
}
|
||||
|
||||
setPriority(priority: number): this {
|
||||
this.priority = priority;
|
||||
return this;
|
||||
}
|
||||
|
||||
//FIXME: arg array. generic이어야하나?
|
||||
abstract action(rng: RandUtil, env: GameEnv, arg: unknown[]): void;
|
||||
|
||||
//FIXME: 재설계 필요.
|
||||
getUniqueID(): string{
|
||||
const priority = this.getPriority();
|
||||
//FIXME: PHP 버전에서 namespace 개념도 옮겨와야하는가?
|
||||
const objName = this.constructor.name;
|
||||
|
||||
return `${priority}:${objName}`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { BaseGeneralTrigger } from "../Trigger/BaseGeneralTrigger.js";
|
||||
import type { ObjectTrigger } from "../Trigger/ObjectTrigger.js";
|
||||
import { TriggerCaller } from "./TriggerCaller.js";
|
||||
|
||||
export class GeneralTriggerCaller extends TriggerCaller<BaseGeneralTrigger> {
|
||||
checkValidTrigger(trigger: ObjectTrigger<object>): boolean {
|
||||
return trigger instanceof BaseGeneralTrigger;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { ObjectTrigger, PRIORITY } from "../Trigger/ObjectTrigger.js";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export abstract class TriggerCaller<T extends ObjectTrigger<any>> {
|
||||
protected triggerListByPriority: Map<number, Map<string, T>>;
|
||||
|
||||
|
||||
abstract checkValidTrigger(trigger: T): boolean;
|
||||
|
||||
isEmpty(): boolean {
|
||||
return this.triggerListByPriority.size === 0;
|
||||
}
|
||||
|
||||
constructor(...triggerList: T[]) {
|
||||
if(triggerList.length === 0){
|
||||
this.triggerListByPriority = new Map();
|
||||
return;
|
||||
}
|
||||
|
||||
this.triggerListByPriority = new Map();
|
||||
let sorted = true;
|
||||
let maxPriority: number = PRIORITY.MIN;
|
||||
|
||||
for (const trigger of triggerList) {
|
||||
const priority = trigger.getPriority();
|
||||
const uniqueID = trigger.getUniqueID();
|
||||
|
||||
if(sorted){
|
||||
if(maxPriority < priority){
|
||||
maxPriority = priority;
|
||||
}
|
||||
else if(maxPriority > priority){
|
||||
sorted = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(this.triggerListByPriority.has(priority)){
|
||||
const subTriggerList = this.triggerListByPriority.get(priority) as Map<string, T>;
|
||||
if(subTriggerList.has(uniqueID)){
|
||||
//TODO: 완성되기 전까진..
|
||||
throw `Duplicated trigger: ${uniqueID}`;
|
||||
}
|
||||
subTriggerList.set(uniqueID, trigger);
|
||||
}
|
||||
else {
|
||||
this.triggerListByPriority.set(priority, new Map([[uniqueID, trigger]]));
|
||||
}
|
||||
}
|
||||
|
||||
if(!sorted){
|
||||
this.triggerListByPriority = new Map([...this.triggerListByPriority.entries()].sort((a, b) => b[0] - a[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { BaseGeneralTrigger } from "../Trigger/BaseGeneralTrigger.js";
|
||||
import type { ObjectTrigger } from "../Trigger/ObjectTrigger.js";
|
||||
import { TriggerCaller } from "./TriggerCaller.js";
|
||||
|
||||
export class WarUnitTriggerCaller extends TriggerCaller<BaseGeneralTrigger> {
|
||||
checkValidTrigger(trigger: ObjectTrigger<object>): boolean {
|
||||
return trigger instanceof BaseGeneralTrigger;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export class WarUnitEnv {
|
||||
|
||||
}
|
||||
|
||||
export abstract class WarUnit{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { WarUnit } from "./WarUnit.js";
|
||||
|
||||
export class WarUnitCity extends WarUnit{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { WarUnit } from "./WarUnit.js";
|
||||
|
||||
export class WarUnitGeneral extends WarUnit{
|
||||
|
||||
}
|
||||
Generated
+3
@@ -212,6 +212,9 @@ importers:
|
||||
'@sammo/api_def':
|
||||
specifier: workspace:^
|
||||
version: link:../api_def
|
||||
'@sammo/crypto':
|
||||
specifier: workspace:^
|
||||
version: link:../crypto
|
||||
'@sammo/server_util':
|
||||
specifier: workspace:^
|
||||
version: link:../server_util
|
||||
|
||||
Reference in New Issue
Block a user