Skip to content

Commit

Permalink
配置伤害函数
Browse files Browse the repository at this point in the history
  • Loading branch information
sumneko committed Nov 25, 2024
1 parent a3bc9ca commit dd440d4
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 29 deletions.
14 changes: 11 additions & 3 deletions src/ecaCompiler/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export class Exp {
name: string;
type: number;
kind: 'action' | 'call' | 'value' = 'call';
args?: Exp[];
args?: (Exp | null)[];
value?: string | number | boolean;
constructor(private json: y3.json.JObject) {
this.type = json.arg_type as number;
Expand All @@ -22,7 +22,9 @@ export class Exp {
}
if ('op_arg' in json) {
for (let op_arg of json.op_arg as y3.json.JObject[]) {
if (op_arg) {
if (op_arg === null) {
this.args.push(null);
} else {
this.args.push(new Exp(op_arg));
}
}
Expand All @@ -40,7 +42,13 @@ export class Exp {
if (this.kind === 'value') {
return formatter.formatValue(this.type, this.value);
} else {
return formatter.formatCall(this.name, this.args!.map((arg) => arg.make(formatter)));
return formatter.formatCall(this.name, this.args!.map((arg) => {
if (arg === null) {
return 'nil';
} else {
return arg.make(formatter);
}
}));
}
}
}
Expand Down
37 changes: 23 additions & 14 deletions src/ecaCompiler/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const OptionalEnd = Symbol('OptionalEnd');

type RulePart = string | number | typeof OptionalStart | typeof OptionalEnd;

type Rule = string | Record<number | string, string> | ((args?: string[]) => string);
type Rule = string | Record<number | string, string> | ((args?: string[]) => string) | null;

class RuleHandler {
constructor(public rule: Rule, public argNames?: string[]) {
Expand Down Expand Up @@ -50,14 +50,18 @@ class RuleHandler {

switch (match[0]) {
case '<?':
let last = parts[parts.length - 1];
if (typeof last === 'string' && last?.endsWith(' ')) {
parts.push(' ');
}
parts.push(OptionalStart);
continue;
case '?>':
parts.push(OptionalEnd);
continue;
default: {
// 添加匹配项
const argName = match[0].slice(1, -1); // 去掉大括号
let argName = match[0].slice(1, -1); // 去掉大括号
if (argName === '') {
parts.push(curDefault);
curDefault++;
Expand Down Expand Up @@ -101,6 +105,9 @@ class RuleHandler {
return children;
}
case 'object': {
if (this.rule === null) {
return NilRuleHandler;
}
let rule = this.rule[args![0]];
if (!rule) {
return DefaultRuleHandler;
Expand All @@ -126,28 +133,30 @@ class RuleHandler {
if (!this._parts) {
this.compile(this.rule as string, args);
}
return this._parts!.map((part) => {
let i;
let buf: string[] = [];
for (i = 0;i < this._parts!.length;i++) {
let part = this._parts![i];
if (typeof part === 'number') {
return args?.[part - 1] ?? 'nil';
}
if (part === OptionalStart || part === OptionalEnd) {
return '';
buf.push(args?.[part - 1] ?? 'nil');
} else if (typeof part === 'string') {
buf.push(part);
} else if (part === OptionalStart) {
} else if (part === OptionalEnd) {
}
return part;
}).join('');
};
return buf.join('');
}
}

let DefaultRuleHandler = new RuleHandler('{}');
let NilRuleHandler = new RuleHandler('nil');

export class Formatter {
public rules = new Map<string | number, RuleHandler>();
public setCallRule(name: string, rule: Rule, argNames?: string[]) {
public setRule(name: string | number, rule: Rule, argNames?: string[]) {
this.rules.set(name, new RuleHandler(rule, argNames));
}

public setValueRule(type: number, rule: Rule) {
this.rules.set(type, new RuleHandler(rule));
return this;
}

public formatCall(name: string, args: string[]) {
Expand Down
65 changes: 53 additions & 12 deletions src/ecaCompiler/testConfig.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,58 @@
/* eslint-disable @typescript-eslint/semi */
import { Formatter } from './formatter';

export function testConfig(formatter: Formatter) {
formatter.setValueRule(100006, 'y3.unit.get_by_res_id({})');
formatter
. setRule(100006, 'y3.unit.get_by_res_id({})')
. setRule(100205, 'y3.destructible.get_by_id({})')
. setRule(100333, {
934231441: '"伤害_左上"',
934269508: '"伤害_中上"',
934266669: '"伤害_右上"',
934252831: '"伤害_左下"',
934277693: '"金币跳字"',
})

formatter.setValueRule(100333, {
934231441: '"伤害_左上"',
934269508: '"伤害_中上"',
934266669: '"伤害_右上"',
934252831: '"伤害_左下"',
934277693: '"金币跳字"',
});

formatter.setCallRule('UNIT_ENTITY_POINT', '{}:get_point()');
formatter.setCallRule('ALL_PLAYER', 'y3.player_group.get_all_players()');
formatter.setCallRule('CREATE_HARM_TEXT_NEW', 'y3.ui.create_floating_text2({point}, {type}, {str}, {jump_word_track}, {player_group})', ['point', 'type', 'str', 'player_group', 'jump_word_track']);
. setRule('UNIT_ENTITY_POINT', '{}:get_point()')
. setRule('ALL_PLAYER', 'y3.player_group.get_all_players()')
. setRule('CREATE_HARM_TEXT_NEW', 'y3.ui.create_floating_text2({point}, {type}, {str}, {jump_word_track}, {player_group})', ['point', 'type', 'str', 'player_group', 'jump_word_track'])
. setRule('SET_DEST_IS_SELECTED', '{}:set_can_be_selected({})')
/*
---@field target Unit|Item|Destructible
---@field type y3.Const.DamageType | integer # 也可以传任意数字
---@field damage number
---@field ability? Ability # 关联技能
---@field text_type? y3.Const.DamageTextType # 跳字类型
---@field text_track? integer # 跳字轨迹类型
---@field common_attack? boolean # 视为普攻
---@field critical? boolean # 必定暴击
---@field no_miss? boolean # 必定命中
---@field particle? py.SfxKey # 特效
---@field socket? string # 特效挂点
---@field attack_type? integer # 攻击类型
---@field pos_socket? string # 目标挂点
*/
. setRule('APPLY_DAMAGE', ''
+ '{unit}:damage {\n'
+ ' target = {target},\n'
+ ' damage = {damage},\n'
+ ' type = {type},\n'
+ ' <?socket = {socket},?>\n'
+ ' <?ability = {ability},?>\n'
+ ' <?no_miss = {no_miss},?>\n'
+ ' <?critical = {critical},?>\n'
+ ' <?particle = {particle},?>\n'
+ ' <?text_type = {text_enable} and {text_type},?>\n'
+ ' <?text_track = {text_track},?>\n'
+ ' <?common_attack = {common_attack},?>\n'
+ ' <?attack_type = {attack_type},?>\n'
+ ' <?pos_socket = {pos_socket},?>\n'
+ '}'
, [
'unit', 'ability', 'target', 'type', 'damage', 'text_enable',
'common_attack', 'critical', 'no_miss', 'particle', 'socket',
'text_type', 'text_track', 'attack_type', 'pos_socket',
]
)
. setRule('NONE_ABILITY', null)
}

0 comments on commit dd440d4

Please sign in to comment.