1

主题

1

回帖

53

积分

普通创作者

积分
53
发表于  2023-10-27 04:18:54 | 显示全部楼层 |阅读模式 1028 4
本帖最后由 大老虎阿#4954 于 2023-10-27 04:21 编辑

痛点:
在技能描述里写一套技能伤害的公式,而不能让技能描述实时显示技能当前能造成伤害的实际数值。

此函数解决了以上痛点:
此函数可以允许你在物编的技能描述中使用变量,如下图:
1.png
发射8个追踪火球,对目标造成f[10 * {skill.d.ability_level} + {unit.ATTR_RESULT.attack_mag} * 0.25]法术伤害。

公式解析:
f[] 表示以实数的方式显示[]内的公式计算结果
格式标准:{来源类型.数据类型.属性名}
{skill.d.ability_level} 解释:此变量表示 技能等级
{unit.ATTR_RESULT.attack_mag} 解释:此变量表示 技能拥有者的实际法术攻击力

更多变量属性名可以自己在ECA转Lua中查看,等我有空的时候我会整理好更新到此贴里。

在游戏中显示的实际效果,如下图:
0W_Q$XB%E[QY2J1(MZR()RS.png

使用方法:
T4([8Z4WR]QF80{FRY{%~KK.png
只需要在设置用来展示技能描述的界面控件的字符串中调用GetActualValue(args[1])并传入需要展示的技能就可以了。
此函数是返回完整的技能描述字符串。

有什么缺陷或者不懂的可以留言,我会尽量回复。

Lua代码:
  1. function StringCalculate(str)
  2.     local function precedence(op)
  3.         local prec = {
  4.             ['+'] = 1,
  5.             ['-'] = 1,
  6.             ['*'] = 2,
  7.             ['/'] = 2
  8.         }
  9.         return prec[op] or 0
  10.     end

  11.     local function apply(op, a, b)
  12.         if op == '+' then return a + b end
  13.         if op == '-' then return a - b end
  14.         if op == '*' then return a * b end
  15.         if op == '/' then return a / b end
  16.     end

  17.     local numbers = {}
  18.     local ops = {}
  19.     local i = 1

  20.     while i <= #str do
  21.         local c = str:sub(i, i)

  22.         if c:match("%d") then
  23.             local start = i
  24.             while i <= #str and str:sub(i, i):match("[%d%.]") do
  25.                 i = i + 1
  26.             end
  27.             local num = str:sub(start, i - 1)
  28.             table.insert(numbers, tonumber(num))
  29.         elseif c:match("[%+%-%*/]") then
  30.             while #ops > 0 and precedence(ops[#ops]) >= precedence(c) do
  31.                 local op = table.remove(ops)
  32.                 local b = table.remove(numbers)
  33.                 local a = table.remove(numbers)
  34.                 table.insert(numbers, apply(op, a, b))
  35.             end
  36.             table.insert(ops, c)
  37.             i = i + 1
  38.         elseif c == '(' then
  39.             table.insert(ops, c)
  40.             i = i + 1
  41.         elseif c == ')' then
  42.             while ops[#ops] ~= '(' do
  43.                 local op = table.remove(ops)
  44.                 local b = table.remove(numbers)
  45.                 local a = table.remove(numbers)
  46.                 table.insert(numbers, apply(op, a, b))
  47.             end
  48.             table.remove(ops)
  49.             i = i + 1
  50.         else
  51.             i = i + 1
  52.         end
  53.     end

  54.     while #ops > 0 do
  55.         local op = table.remove(ops)
  56.         local b = table.remove(numbers)
  57.         local a = table.remove(numbers)
  58.         table.insert(numbers, apply(op, a, b))
  59.     end

  60.     return numbers[1]
  61. end

  62. function GetActualValue(cskill)--传入参数:技能

  63.         --技能介绍:发射追踪火球,对目标造成f[10 * {skill.d.ability_level} + {unit.ATTR_RESULT.attack_mag} * 0.25]法术伤害。
  64.         --字符串运算说明:f[运算公式]显示为实数 d[运算公式]显示未整数
  65.         --变量说明:{来源.类型.属性名}
  66.         --来源:skill=技能 unit=单位
  67.         --类型:skill.d=整数 skill.f=实数 unit.ATTR_RESULT=实际属性
  68.         --属性名:skill.d.ability_level = 技能等级 unit.ATTR_RESULT.attack_mag = 法术攻击力
  69.         --ECA用法:字符串变量 = 执行Lua代码 GetActualValue(args[1]) 参数1传入技能
  70.         
  71.         local Skill = y3.ability.get_lua_ability_from_py(cskill);
  72.         local Unit = Skill:get_owner();--获取技能单位
  73.         local Description = Skill:get_string_attr("description");--获取技能描述
  74.         for FromType,ValueType,DataName in string.gmatch(Description, "{(.-)%.(.-)%.(.-)}") do
  75.                 local ValueTSID = 100000;
  76.                 local Value = 0;
  77.                 if (FromType == "skill")then
  78.                         if (ValueType == "d")then
  79.                                 ValueTSID = 100002;
  80.                                 Value = Skill:get_int_attr(DataName);
  81.                         elseif (ValueType == "f")then
  82.                                 ValueTSID = 100000;
  83.                                 Value = Skill:get_float_attr(DataName);
  84.                         end
  85.                         Description = string.gsub(Description, string.format("{%s.%s.%s}", FromType, ValueType, DataName), y3.any_var_to_str(ValueTSID, Value));
  86.                 elseif (FromType == "unit")then
  87.                         if (ValueType == "d")then
  88.                                 ValueTSID = 100002;
  89.                                 if (DataName == "level")then
  90.                                         Value = Unit:get_level();
  91.                                 end
  92.                         else
  93.                                 ValueTSID = 100000;
  94.                                 Value = Unit:get(ValueType,DataName);
  95.                         end
  96.                         Description = string.gsub(Description, string.format("{%s.%s.%s}", FromType, ValueType, DataName), y3.any_var_to_str(ValueTSID, Value));
  97.                 end
  98.         end
  99.         for ValueData in string.gmatch(Description, "d%[(.-)%]") do
  100.                 local Value = StringCalculate(ValueData);
  101.                 local DataStr = string.format("f[%s]", ValueData);
  102.                 Description = string.gsub(Description, DataStr:gsub("([^%w])", "%%%1"), y3.any_var_to_str(100002, Value));--替换对应数据
  103.         end
  104.         for ValueData in string.gmatch(Description, "f%[(.-)%]") do
  105.                 local Value = StringCalculate(ValueData);
  106.                 local DataStr = string.format("f[%s]", ValueData);
  107.                 Description = string.gsub(Description, DataStr:gsub("([^%w])", "%%%1"), y3.any_var_to_str(100000, Value));--替换对应数据
  108.         end

  109.         return Description;
  110. end
复制代码



1

主题

1

回帖

53

积分

普通创作者

积分
53
发表于  2023-10-30 11:31:02 | 显示全部楼层
字符串公式计算可以用load函数代替,在写StringCalculate函数前尝试过loadstring但发现用不了,才写的StringCalculate函数。
我建议还是使用原生函数load更好。

9

主题

6

回帖

149

积分

普通创作者

积分
149
发表于  2023-10-30 17:07:22 | 显示全部楼层
666666666666666666666666666666

0

主题

1

回帖

9

积分

新手上路

积分
9
发表于  2023-10-31 18:37:09 | 显示全部楼层
7777777777777777777777777777

11

主题

4

回帖

254

积分

优秀创作者

积分
254
发表于  2023-11-3 18:56:45 | 显示全部楼层
66666666666666