1 local print, verb, dbg, errr, print_table, printt = make_module_loggers("schema", "SCM")
5 = import 'game/const.lua'
13 = import (game_const.abilities)
19 local AP, abiprob_mapping = import (game_const.abilities.property)
21 'mappingInv', -- Note order (inverted goes first)
25 local PO, CM, CST, SO,
27 = import 'abie/const.lua'
39 get_children_concat_newline,
40 get_children_concat_str,
41 get_children_concat_table,
45 check_mapping_tonumber,
46 get_value_mapped_tonumber_quoted,
47 node_children_placeholders_filler,
49 = import 'jsle/schema/util.lua'
55 'get_children_concat_newline',
56 'get_children_concat_str',
57 'get_children_concat_table',
61 'check_mapping_tonumber',
62 'get_value_mapped_tonumber_quoted',
63 'node_children_placeholders_filler',
67 local declare_common = import 'jsle/schema/common.lua' { 'declare_common' }
71 -- TODO: Must be able to fetch back data from lang file to this schema.
72 -- TODO: Write effect validation with human readable answers. Make it available via jobman's job.
73 -- TODO: Write auto-conversion function for old abilities (v.1.01->current)
74 -- TODO: Embed limitations on number of simultanious identical active OT effects
75 -- TODO: Write checkers for numeric fields
76 -- TODO: Adapt game/ctrl.lua to abie
78 local define_schema = function(jsle)
81 -- WARNING: Return nil on error from handlers, do not return false -- it is a legitimate value.
82 -- WARNING: Reordering of schema elements would result in INCOMPATIBLE format change!
84 local propwrite_values =
86 { ["health"] = [[жизнь]] };
87 { ["health_max"] = [[здоровье]] };
88 { ["mana1"] = [[красную ману]] };
89 { ["mana2"] = [[зелёную ману]] };
90 { ["mana3"] = [[синюю ману]] };
91 -- Note mana4 is reserved for health
92 { ["mana5"] = [[ману 5]] };
93 { ["mana6"] = [[ману 6]] };
94 { ["mana7"] = [[ману 7]] };
95 { ["mana8"] = [[ману 8]] };
96 { ["armor"] = [[броню]] };
97 { ["fury"] = [[ярость]] };
98 { ["block"] = [[блок]] };
99 { ["fortune"] = [[удачу]] };
100 { ["stun"] = [[оглушение]] };
101 { ["armour_piercing"] = [[бронебойность]] };
102 { ["agility"] = [[ловкость]] };
103 { ["counterattack"] = [[контрудар]] };
104 { ["damage"] = [[базовый урон]] };
105 { ["damage_min"] = [[минимальный урон]] };
106 { ["damage_max"] = [[максимальный урон]] };
107 { ["damage_mult"] = [[множитель урона]] };
108 { ["vampiric"] = [[вампиризм]] };
109 { ["stun_count"] = [[оглушённость]] };
112 local propread_values = tiappend(
113 tclone(propwrite_values),
115 { ["race_id"] = [[расу]] },
116 { ["level"] = [[уровень]] },
117 { ["grade"] = [[степень]] }, -- TODO: clan_rank?!
118 { ["rank"] = [[ранг]] },
119 { ["glory"] = [[доблесть]] },
120 { ["scalps"] = [[скальпы]] },
121 { ["kills"] = [[убийства]] },
125 -- TODO: Be more specific. Should be at least "abie-1.03".
126 jsle:version("1.03") -- WARNING: Do an ordering cleanup when this changes
133 [2] = "IMMEDIATE_EFFECT_LIST";
134 [3] = "OVERTIME_EFFECT";
135 [4] = { "BOOLEAN", default = 0 }; -- Warning! Do not use BOOLOP_VARIANT, nothing of it would work at this point.
136 [5] = { "CUSTOM_OVERTIME_EFFECTS", default = empty_table };
138 html = [[<h2>Цели</h2>%C(1)%<h2>Мгновенные эффекты</h2><b>Игнорировать активацию в статистике:</b>%C(4)%<br><br><b>Действия:</b>%C(2)%<h2>Овертайм-эффекты</h2>%C(3)%<hr>%C(5)%]];
140 handler = function(self, node)
141 return self:effect_from_string(
142 node.value[1], -- Target list
143 node.value[4], -- Ignore usage stats flag
144 self:fill_placeholders(
148 self:set_custom_ot_effects($(5))
164 jsle:list "TARGET_LIST"
166 type = "TARGET_VALUE";
167 html = [[%LIST(", ")%]];
168 checker = non_empty_list;
169 handler = function(self, node)
171 for i, v in ipairs(node.value) do
178 jsle:enum "TARGET_VALUE"
182 { [MTF.AUTO_ONLY] = [[неинтерактивно]] };
183 { [MTF.SELF_HUMAN] = [[на себя]] };
184 { [MTF.SELF_TEAM_HUMAN] = [[на человека в своей команде]] };
185 { [MTF.OPP_HUMAN] = [[на противника]] };
186 { [MTF.OPP_TEAM_HUMAN] = [[на человека в команде противника]] };
187 { [MTF.FIELD_CHIP] = [[на фишку]] };
189 html = [[%VALUE()%]];
191 handler = get_value_tonumber;
195 jsle:list "IMMEDIATE_EFFECT_LIST"
197 type = "ACTION_VARIANT";
198 html = [[%LE("<i>Нет</i>")%%LNE("<ol><li>")%%LIST("<li>")%%LNE("</ol>")%]];
200 handler = get_children_concat_newline;
203 jsle:record "OVERTIME_EFFECT"
207 [1] = "OT_EFFECT_TARGET";
208 [2] = "NUMOP_VARIANT";
209 [3] = "NUMOP_VARIANT";
210 [4] = "BOOLOP_VARIANT";
211 [5] = "OVERTIME_EFFECT_LIST";
212 [6] = "OVERTIME_EFFECT_LIST";
213 [7] = "OVERTIME_EFFECT_LIST";
214 [8] = "OT_MODIFIER_LIST";
215 [9] = "NUMOP_VARIANT"; -- TODO: Must be higher in the list. Straighten numbers on next version change (do not forget to fix texts)
216 [10] = "NUMOP_VARIANT"; -- TODO: Must be higher in the list. Straighten numbers on next version change (do not forget to fix texts)
217 [11] = { "GAME_MODES", default = GMF.ALL }; -- TODO: Must be higher in the list. Straighten numbers on next version change (do not forget to fix texts)
218 [12] = { "BOOLEAN", default = 0 };
220 html = [[<br><b>Цель:</b> %C(1)%<br><b>Время жизни:</b> %C(2)% <i>(≥255 — бессрочно)</i><br><b>Период:</b> %C(3)%<br><b>Изначальный кулдаун:</b> %C(10)%<br><b>Сброс в конце боя:</b> %C(4)%<br><b>Остается при снятии всех эффектов вручную:</b> %C(12)%<br><b>Максимальное число одновременно активных эффектов:</b> %C(9)% <i>(0 — не ограничено)</i><br><b>Игровые режимы:</b> %C(11)%<h3>При изменении набора характеристик</h3>%C(5)%<h3>В конце хода цели</h3>%C(7)%<h3>Временные модификаторы <i>(кроме жизни)</i></h3>%C(8)%]];
222 handler = function(self, node)
224 node.value[5] ~= "" or
225 node.value[6] ~= "" or
226 node.value[7] ~= "" or
227 node.value[8] ~= "{}"
229 -- Spawning OT effect only if have any actions in it.
230 return node_children_placeholders_filler
232 self:spawn_overtime_effect(
254 return [[-- No OT effects]]
259 jsle:list "OT_MODIFIER_LIST"
261 type = "OT_MODIFIER_VARIANT";
262 html = [[%LE("<i>Нет</i>")%%LNE("<ol><li>")%%LIST("<li>")%%LNE("</ol>")%]];
264 handler = get_children_concat_table;
267 jsle:variant "OT_MODIFIER_VARIANT"
271 { ["MOD_SET"] = [[Установить]] };
272 { ["MOD_INC"] = [[Увеличить]] };
273 { ["MOD_DEC"] = [[Уменьшить]] };
274 { ["MOD_MULT"] = [[Умножить]] };
276 label = [["<i title=\"Модификатор\">M</i>"]];
277 html = [[%VALUE()%]];
282 jsle:record "MOD_SET"
287 [2] = "NUMOP_VARIANT";
289 html = [[Установить %C(1)% цели в %C(2)%]];
291 handler = node_children_placeholders_filler [[{ name = $(1), fn = function(self, value) return ($(2)) end; }]];
294 jsle:record "MOD_INC"
299 [2] = "NUMOP_VARIANT";
301 html = [[Увеличить %C(1)% цели на %C(2)%]];
303 handler = node_children_placeholders_filler [[{ name = $(1), fn = function(self, value) return value + ($(2)) end; }]];
306 jsle:record "MOD_DEC"
311 [2] = "NUMOP_VARIANT";
313 html = [[Уменьшить %C(1)% цели на %C(2)%]];
315 handler = node_children_placeholders_filler [[{ name = $(1), fn = function(self, value) return value - ($(2)) end; }]];
318 jsle:record "MOD_MULT"
323 [2] = "NUMOP_VARIANT";
325 html = [[Умножить %C(1)% цели на %C(2)%]];
327 handler = node_children_placeholders_filler [[{ name = $(1), fn = function(self, value) return value * ($(2)) end; }]];
330 jsle:list "OVERTIME_EFFECT_LIST"
332 type = "ACTION_VARIANT";
333 html = [[%LE("<i>Нет</i>")%%LNE("<ol><li>")%%LIST("<li>")%%LNE("</ol>")%]];
335 handler = get_children_concat_newline;
338 jsle:list "ACTION_LIST"
340 type = "ACTION_VARIANT";
341 html = [[<ol><li>%LIST("<li>")%</ol>]];
342 checker = non_empty_list;
343 handler = get_children_concat_newline;
346 jsle:variant "ACTION_VARIANT"
350 { ["ACT_SET"] = [[Установить]] };
351 { ["ACT_INC"] = [[Увеличить]] };
352 { ["ACT_DEC"] = [[Уменьшить]] };
353 { ["ACT_MULT"] = [[Умножить]] };
354 { ["ACT_DIRECTSET"] = [[Установить напрямую]] };
355 { ["ACT_DIRECTINC"] = [[Увеличить напрямую]] };
356 { ["ACT_DIRECTDEC"] = [[Уменьшить напрямую]] };
357 { ["ACT_DIRECTMULT"] = [[Умножить напрямую]] };
358 { ["ACT_FLDEXPLODE"] = [[Взорвать фишки]] };
359 { ["ACT_FLDLEVELDELTA"] = [[Поднять уровень фишек]] };
360 { ["ACT_FLDCOLLECT_COORDS"] = [[Собрать фишки по координатам]] };
361 { ["ACT_FLDREPLACE_COORDS"] = [[Заменить фишки по координатам]] };
362 { ["ACT_ONEMOREACTION"] = [[Дать ещё одно действие]] };
363 { ["ACT_KEEPTIMEOUT"] = [[Не сбрасывать таймер]] };
364 { ["ACT_SETVAR"] = [[Запомнить]] };
365 { ["ACT_SETOBJVAR_LOCAL"] = [[Запомнить в объекте локально]] };
366 { ["ACT_SETOBJVAR_GLOBAL"] = [[Запомнить в объекте глобально]] };
367 { ["ACT_SETOBJVAR_OT"] = [[Запомнить в текущем овертайме]] };
368 { ["ACT_DOIF"] = [[Если]] };
369 { ["ACT_DOIFELSE"] = [[Если ... иначе]] };
370 { ["ACT_PLAYABIANIM"] = [[Играть эффект абилки]] };
371 { ["ACT_SENDCUSTOMMSG"] = [[Отправить данные клиентам]] };
372 { ["ACT_INCSTAT"] = [[Увеличить статистику клиента]] };
373 { ["ACT_ACTIVATEOT"] = [[Активировать ОТ-эффект]] };
374 { ["ACT_REMOVE_OVERTIMES"] = [[Снять ОТ-эффекты]] };
375 -- Keep these below --
376 { ["ACT_FLDREPLACE"] = [[Заменить фишки <b><i>(устарело)</i></b>]] };
377 { ["ACT_CRASH_GAME"] = [[УРОНИТЬ игру <b><i>(только для тестов)</i></b>]] };
378 -- { ["PLAINLUA"] = [[Lua]] };
380 label = [["<i title=\"Действие\">A</i>"]];
381 html = [[%VALUE()%]];
386 declare_common(jsle, "ACT_DOIF", "ACT_DOIFELSE")
388 jsle:record "ACT_SET"
392 [1] = "PROPPATH_WRITE";
393 [2] = "NUMOP_VARIANT";
395 html = [[Установить %C(1)% в %C(2)%]];
397 handler = node_children_placeholders_filler [[self:propset($(1), $(2))]];
400 jsle:record "ACT_INC"
404 [1] = "PROPPATH_WRITE";
405 [2] = "NUMOP_VARIANT";
407 html = [[Увеличить %C(1)% на %C(2)%]];
409 handler = node_children_placeholders_filler [[self:propinc($(1), $(2))]];
412 jsle:record "ACT_DEC"
416 [1] = "PROPPATH_WRITE";
417 [2] = "NUMOP_VARIANT";
419 html = [[Уменьшить %C(1)% на %C(2)%]];
421 handler = node_children_placeholders_filler [[self:propdec($(1), $(2))]];
424 jsle:record "ACT_MULT"
428 [1] = "PROPPATH_WRITE";
429 [2] = "NUMOP_VARIANT";
431 html = [[Умножить %C(1)% на %C(2)%]];
433 handler = node_children_placeholders_filler [[self:propmult($(1), $(2))]];
436 jsle:record "ACT_DIRECTSET"
440 [1] = "PROPPATH_WRITE";
441 [2] = "NUMOP_VARIANT";
443 html = [[Установить напрямую %C(1)% в %C(2)%]];
445 handler = node_children_placeholders_filler [[self:propset_direct($(1), $(2))]];
448 jsle:record "ACT_DIRECTINC"
452 [1] = "PROPPATH_WRITE";
453 [2] = "NUMOP_VARIANT";
455 html = [[Увеличить напрямую %C(1)% на %C(2)%]];
457 handler = node_children_placeholders_filler [[self:propinc_direct($(1), $(2))]];
460 jsle:record "ACT_DIRECTDEC"
464 [1] = "PROPPATH_WRITE";
465 [2] = "NUMOP_VARIANT";
467 html = [[Уменьшить напрямую %C(1)% на %C(2)%]];
469 handler = node_children_placeholders_filler [[self:propdec_direct($(1), $(2))]];
472 jsle:record "ACT_DIRECTMULT"
476 [1] = "PROPPATH_WRITE";
477 [2] = "NUMOP_VARIANT";
479 html = [[Умножить напрямую %C(1)% на %C(2)%]];
481 handler = node_children_placeholders_filler [[self:propmult_direct($(1), $(2))]];
484 jsle:record "ACT_FLDEXPLODE"
488 [1] = "NUMOP_VARIANT";
491 html = [[Взорвать бомбу радиусом %C(1)% в координатах %C(2)%]];
493 handler = node_children_placeholders_filler [[self:fld_explode($(1), $(2))]];
496 jsle:record "ACT_FLDREPLACE"
501 [2] = "NUMOP_VARIANT";
503 [4] = "NUMOP_VARIANT";
505 html = [[Заменить %C(1)% уровня %C(2)% на %C(3)% уровня %C(4)%]];
507 handler = node_children_placeholders_filler [[self:fld_replace($(1), $(2), $(3), $(4))]];
508 doc = [[Deprecated, use other replace actions]];
511 jsle:record "ACT_FLDLEVELDELTA"
515 [1] = "NUMOP_VARIANT";
517 [3] = "NUMOP_VARIANT";
518 [4] = "NUMOP_VARIANT";
520 html = [[Поднять уровень %C(2)% на %C(1)% в диапазоне от %C(3)% до %C(4)%]];
522 handler = node_children_placeholders_filler [[self:fld_level_delta($(1), $(2), $(3), $(4))]];
525 jsle:record "ACT_FLDCOLLECT_COORDS"
529 [1] = "COORDLISTOP_VARIANT";
531 html = [[Собрать %C(1)%]];
533 handler = node_children_placeholders_filler [[self:fld_collect_coords($(1))]];
536 jsle:record "ACT_FLDREPLACE_COORDS"
540 [1] = "COORDLISTOP_VARIANT";
541 [2] = "CHIPTYPE_LIST";
542 [3] = "NUMOP_VARIANT";
544 html = [[Заменить %C(1)% на %C(2)% уровня %C(3)%]];
546 handler = node_children_placeholders_filler [[self:fld_replace_coords($(1),$(2),$(3))]];
549 jsle:literal "ACT_ONEMOREACTION"
551 html = [[Дать ещё одно действие <i>(только мгновенный эффект)</i>]];
553 handler = invariant [[self:one_more_action()]];
556 jsle:literal "ACT_KEEPTIMEOUT"
558 html = [[Не сбрасывать таймер <i>(только мгновенный эффект)</i>]];
560 handler = invariant [[self:keep_timeout()]];
563 jsle:record "ACT_SETVAR"
567 [1] = "NUMOP_VARIANT";
568 [2] = "NUMOP_VARIANT";
570 html = [[Запомнить в №%C(1)% значение %C(2)%]];
572 handler = node_children_placeholders_filler [[self:setvar($(1), $(2))]];
575 jsle:enum "OT_EFFECT_TARGET"
579 { [PO.SELF] = [[на себя]] };
580 { [PO.OPP] = [[на противника]] };
581 { [PO.TARGET] = [[на цель]] };
583 html = [[%VALUE()%]];
585 handler = get_value_quoted;
588 jsle:variant "BOOLOP_VARIANT"
592 { ["BOOLEAN"] = [[Логическое значение]] };
593 { ["BOOLOP_LT"] = [[<]] };
594 { ["BOOLOP_LTE"] = [[≤]] };
595 { ["BOOLOP_GT"] = [[>]] };
596 { ["BOOLOP_GTE"] = [[≥]] };
597 { ["BOOLOP_EQ"] = [[==]] };
598 { ["BOOLOP_NEQ"] = [[!=]] };
599 { ["BOOLOP_AND_MANY"] = [[И (Список)]] };
600 { ["BOOLOP_OR_MANY"] = [[ИЛИ (Список)]] };
601 { ["BOOLOP_NOT"] = [[НЕ]] };
602 { ["BOOLOP_HAVEMEDAL"] = [[МЕДАЛЬ]] };
603 { ["BOOLOP_ISACTIVE"] = [[Изменения инициированы целью овертайм-эффекта]] };
604 { ["BOOLOP_IS_GAME_IN_MODE"] = [[Текущий игровой режим]] };
605 -- Deprecated, keep below --
606 { ["BOOLOP_AND"] = [[И]] };
607 { ["BOOLOP_OR"] = [[ИЛИ]] };
608 --{ ["PLAINLUA"] = [[Lua]] };
610 label = [["<i title=\"Логическая операция\">B</i>"]];
611 html = [[%VALUE()%]];
616 jsle:record "BOOLOP_HAVEMEDAL"
621 [2] = "NUMOP_VARIANT";
623 html = [[есть медаль №%C(2)% %C(1)%]];
625 handler = node_children_placeholders_filler [[self:have_medal($(1), $(2))]];
628 jsle:literal "BOOLOP_ISACTIVE"
630 html = [[изменения инициированы целью овертайм-эффекта]];
631 checker = no_check; -- Only for on_changeset event.
632 handler = invariant [[self:is_overtime_target_active()]];
648 jsle:variant "NUMOP_VARIANT"
652 { ["NUMBER"] = [[Число]] };
653 { ["NUMOP_ADD_MANY"] = [[+ (Список)]] };
654 { ["NUMOP_DEC_MANY"] = [[- (Список)]] };
655 { ["NUMOP_MUL_MANY"] = [[* (Список)]] };
656 { ["NUMOP_DIV_MANY"] = [[/ (Список)]] };
657 { ["NUMOP_POV"] = [[POW]] }; -- TODO: POW, not POV! Fix by search and replace
658 { ["NUMOP_MOD"] = [[MOD]] };
659 { ["NUMOP_MIN"] = [[MIN]] };
660 { ["NUMOP_MAX"] = [[MAX]] };
661 { ["NUMOP_UNM"] = [[Знак]] };
662 { ["NUMOP_GET"] = [[Характеристика]] };
663 { ["NUMOP_GET_RAW"] = [[Базовое значение характеристики]] };
664 { ["NUMOP_GET_ABIPROP"] = [[Характеристика абилки]] };
665 { ["NUMOP_PERCENT_ROLL"] = [[Cлучайный процент]] };
666 { ["NUMOP_TEAMSIZE"] = [[Размер команды]] };
667 { ["NUMOP_GETVAR"] = [[Вспомнить]] };
668 { ["NUMOP_GETOBJVAR_LOCAL"] = [[Вспомнить из объекта локально]] };
669 { ["NUMOP_GETOBJVAR_GLOBAL"] = [[Вспомнить из объекта глобально]] };
670 { ["NUMOP_GETOBJVAR_OT"] = [[Вспомнить из текущего овертайма]] };
671 { ["NUMOP_OTLIFETIMELEFT"] = [[Оставшееся время жизни]] };
672 { ["NUMOP_OTLIFETIMETOTAL"] = [[Общее время жизни]] };
673 { ["NUMOP_FLDGETQUANTITYOFCHIPS"] = [[Число фишек по цвету и уровню]] };
674 { ["NUMOP_TARGETX"] = [[Координата X выбранной фишки]] };
675 { ["NUMOP_TARGETY"] = [[Координата Y выбранной фишки]] };
676 { ["NUMOP_OTEFFECTCOUNT"] = [[Число активных овертайм-эффектов]] };
677 { ["NUMOP_IFF"] = [[Если]] };
678 { ["NUMOP_GETUID"] = [[Идентификатор игрока]] };
679 -- Keep these below --
680 { ["NUMOP_FLDCOUNTCHIPS"] = [[Число фишек на поле <b><i>(устарело)</i></b>]] };
681 { ["NUMOP_ADD"] = [[+]] };
682 { ["NUMOP_DEC"] = [[-]] };
683 { ["NUMOP_MUL"] = [[*]] };
684 { ["NUMOP_DIV"] = [[/]] };
685 { ["NUMOP_CRASH_GAME"] = [[УРОНИТЬ игру <b><i>(только для тестов)</i></b>]] };
686 --{ ["PLAINLUA"] = [[Lua]] };
688 label = [["<i title=\"Численная операция\">I</i>"]];
689 html = [[%VALUE()%]];
707 jsle:record "NUMOP_GET"
711 [1] = "PROPPATH_READ";
715 handler = node_children_placeholders_filler [[self:propget($(1), false)]];
718 declare_common(jsle, "NUMOP_PERCENT_ROLL")
720 jsle:record "NUMOP_FLDCOUNTCHIPS"
725 [2] = "BOOLOP_VARIANT";
727 html = [[число %C(1)% на поле (учитывая уровни: %C(2)%)]];
729 handler = node_children_placeholders_filler [[self:fld_count_chips($(1), $(2))]];
730 doc = [[Deprecated, use other chip count operations]];
733 jsle:record "NUMOP_TEAMSIZE"
739 html = [[размер команды %C(1)%]];
741 handler = node_children_placeholders_filler [[self:team_size($(1))]];
744 jsle:record "NUMOP_GETVAR"
748 [1] = "NUMOP_VARIANT";
750 html = [[вспомнить из №%C(1)%]];
752 handler = node_children_placeholders_filler [[self:getvar($(1))]];
755 jsle:literal "NUMOP_OTLIFETIMELEFT"
757 html = [[оставшееся время жизни]];
759 handler = invariant [[self:ot_lifetime_left()]];
762 jsle:literal "NUMOP_OTLIFETIMETOTAL"
764 html = [[общее время жизни]];
766 handler = invariant [[self:ot_lifetime_total()]];
769 jsle:literal "NUMOP_TARGETX"
771 html = [[X выбранной фишки]];
773 handler = invariant [[self:target_x()]];
776 jsle:literal "NUMOP_TARGETY"
778 html = [[Y выбранной фишки]];
780 handler = invariant [[self:target_y()]];
783 jsle:record "PROPPATH_WRITE"
790 html = [[%C(2)% %C(1)%]];
792 handler = node_children_placeholders_filler [[self:make_proppath($(1), $(2))]];
795 jsle:record "PROPPATH_READ"
802 html = [[%C(2)% %C(1)%]];
804 handler = node_children_placeholders_filler [[self:make_proppath($(1), $(2))]];
807 jsle:enum "PROPOBJECT"
811 { [PO.SELF] = [[у себя]] };
812 { [PO.OPP] = [[у противника]] };
813 { [PO.TARGET] = [[у цели]] };
814 { [PO.OWN_CHANGESET] = [[в своём наборе изменений]] };
815 { [PO.OPP_CHANGESET] = [[в наборе изменений противника]] };
817 html = [[%VALUE()%]];
818 checker = no_check; -- Check value is valid for current action list subtype
819 handler = get_value_quoted;
822 jsle:enum "PROPWRITE"
824 values = propwrite_values;
825 html = [[%VALUE()%]];
827 handler = get_value_quoted;
832 values = propread_values;
833 html = [[%VALUE()%]];
835 handler = get_value_quoted;
842 { [CT.EMERALD] = [[зелёных фишек]] };
843 { [CT.RUBY] = [[красных фишек]] };
844 { [CT.AQUA] = [[синих фишек]] };
845 { [CT.DMG] = [[черепов]] };
846 { [CT.CHIP5] = [[фишек-5]] };
847 { [CT.CHIP6] = [[фишек-6]] };
848 { [CT.CHIP7] = [[фишек-7]] };
849 { [CT.CHIP8] = [[фишек-8]] };
850 { [CT.EMPTY] = [[пустых фишек]] };
852 html = [[%VALUE()%]];
854 handler = get_value_tonumber;
862 checker = check_tonumber;
863 handler = get_value_tonumber;
872 jsle:list "COORDLISTOP_STD"
875 html = [[фишки с координатами %LIST(", ")%]];
876 checker = non_empty_list;
877 handler = get_children_concat_table;
880 jsle:record "CHIPCOORD"
884 [1] = "NUMOP_VARIANT";
885 [2] = "NUMOP_VARIANT";
887 html = [[(x: %C(1)%, y: %C(2)%)]];
889 handler = node_children_placeholders_filler [[{x=$(1), y=$(2)}]];
892 -- TODO: UNUSED. Remove or use.
893 jsle:record "BOOLOP_SELECTEDTARGET"
897 [1] = "TARGET_VALUE";
899 html = [[выбрана цель %C(1)%]];
901 handler = node_children_placeholders_filler [[self:is_target_selected($(1))]];
902 doc = [[Currently not used]];
905 jsle:record "NUMOP_OTEFFECTCOUNT"
910 [2] = "NUMOP_VARIANT";
911 [3] = "NUMOP_VARIANT";
913 html = [[число овертайм-эффектов абилки ID %C(2)% <i>(0 — этот эффект)</i> № эффекта %C(3)% <i>(0 — по умолчанию)</i>, активных %C(1)%]];
915 handler = node_children_placeholders_filler [[self:active_ot_effect_count($(1), $(2), $(3))]];
918 declare_common(jsle, "NUMOP_IFF")
920 jsle:record "NUMOP_GET_RAW"
924 [1] = "PROPPATH_READ";
926 html = [[базовое значение %C(1)%]];
928 handler = node_children_placeholders_filler [[self:propget($(1), true)]];
931 -- TODO: Get rid of non-list versions!
947 jsle:list "CHIPTYPE_LIST"
950 html = [[%LIST(", ")%]];
951 checker = non_empty_list;
952 handler = get_children_concat_table;
955 jsle:record "NUMOP_GET_ABIPROP"
959 [1] = "ABIPROP_NAME";
961 html = [[%C(1)% абилки]];
963 handler = node_children_placeholders_filler [[self:abipropget($(1))]];
966 jsle:enum "ABIPROP_NAME"
970 { [AP.prob] = [[вероятность активации]] };
972 html = [[%VALUE()%]];
973 checker = check_mapping_tonumber;
974 handler = get_value_mapped_tonumber_quoted(abiprob_mapping);
977 jsle:record "ACT_SENDCUSTOMMSG"
983 html = [[Отправить участникам боя данные: %C(1)%]];
985 handler = node_children_placeholders_filler [[self:send_custom_msg($(1))]];
988 declare_common(jsle, "NUMOP_LIST")
990 jsle:record "ACT_PLAYABIANIM"
994 [1] = "NUMOP_VARIANT";
996 html = [[Играть эффект абилки ID: %C(1)%]];
998 -- Hack. Should format be hardcoded here or below?
999 handler = node_children_placeholders_filler(
1000 [[self:send_custom_msg({]]..assert_is_number(CM.PLAYABIANIM)
1001 ..[[, $(1), self:get_uid("]]..PO.SELF..[[")})]]
1005 jsle:variant "COORDLISTOP_VARIANT"
1009 { ["COORDLISTOP_STD"] = [[Обычный список коордтнат]] };
1010 { ["COORDLISTOP_GETLEVEL"] = [[Фишки цвета <i>цв1</i> с уровнями от <i>ур1</i> до <i>ур2</i>]] };
1012 label = [["<i title=\"Список координат\">C</i>"]];
1013 html = [[%VALUE()%]];
1015 handler = get_value;
1018 jsle:record "COORDLISTOP_GETLEVEL"
1023 [2] = "NUMOP_VARIANT";
1024 [3] = "NUMOP_VARIANT";
1026 html = [[%C(1)% с уровнями от %C(2)% до %C(3)%]];
1028 handler = node_children_placeholders_filler [[self:fld_get_coordlist_from_levels_and_type($(1), $(2), $(3))]];
1031 jsle:record "NUMOP_FLDGETQUANTITYOFCHIPS"
1036 [2] = "NUMOP_VARIANT";
1037 [3] = "NUMOP_VARIANT";
1038 [4] = "BOOLOP_VARIANT";
1040 html = [[число %C(1)% на поле уровней с %C(2)% до %C(3)% (учитывая уровень в счетчике: %C(4)%)]];
1042 handler = node_children_placeholders_filler [[self:fld_get_quantity_of_chips($(1), $(2), $(3), $(4))]];
1045 jsle:enum "CLIENTSTAT"
1049 -- TODO: Support commented out variants?
1050 { [CST.SPELL_USE] = [[исп. спеллов]] };
1051 --{ [CST.SPELL_FRAG] = [[фраги от спеллов]] };
1052 { [CST.CONSUMABLE_USE] = [[исп. расходников]] };
1053 --{ [CST.CONSUMABLE_FRAG] = [[фраги от расходников]] };
1054 { [CST.AUTOABILITY_USE] = [[исп. автоабилок]] };
1055 --{ [CST.AUTOABILITY_FRAG] = [[фраги от автоабилок]] };
1056 --{ [CST.RATING] = [[рейтинг]] };
1057 --{ [CST.CUSTOM] = [[пользовательская]] };
1059 html = [[%VALUE()%]];
1060 checker = check_mapping_tonumber;
1061 handler = get_value_tonumber;
1064 jsle:record "ACT_INCSTAT"
1070 [3] = "NUMOP_VARIANT";
1071 [4] = "NUMOP_VARIANT";
1073 html = [[Увеличить %C(1)% статистику «%C(2)%» эффекта №%C(3)% <i>(0 — текущий)</i> на %C(4)%]];
1075 handler = node_children_placeholders_filler [[self:inc_client_stat($(1), $(2), $(3), $(4))]];
1078 jsle:record "ACT_ACTIVATEOT"
1082 [1] = "NUMOP_VARIANT";
1083 [2] = { "KEYVALUE_LIST", default = empty_table };
1085 html = [[Активировать ОТ-эффект №%C(1)%, передав %C(2)%]];
1087 handler = node_children_placeholders_filler [[self:activate_custom_ot_effect($(1),$(2))]];
1090 jsle:list "CUSTOM_OVERTIME_EFFECTS"
1092 type = "OVERTIME_EFFECT";
1093 html = [[%LE("<i>(Нет дополнительных ОТ-эффектов)</i>")%%LNE("<ol><li><h2>Дополнительный OT-эффект</h2>")%%LIST("<hr><li><h2>Дополнительный OT-эффект</h2>")%%LNE("</ol>")%]];
1095 handler = function(self, node)
1097 local _ = function(v) buf[#buf + 1] = tostring(v) end
1098 for i, child in ipairs(node.value) do
1100 []] _(i) _[[] = function(self)
1106 return table.concat(buf)
1110 jsle:record "NUMOP_GETUID"
1116 html = [[идентификатор игрока %C(1)%]];
1118 handler = node_children_placeholders_filler [[self:get_uid($(1))]];
1121 jsle:enum "STORE_OBJ"
1125 { [SO.CLIENT_SELF] = [[на себе]] };
1126 { [SO.CLIENT_OPP] = [[на противнике]] };
1127 { [SO.CLIENT_TARGET] = [[на цели]] };
1128 { [SO.FIGHT] = [[на бою]] };
1129 { [SO.GAME] = [[на игре]] };
1131 html = [[%VALUE()%]];
1133 handler = get_value_tonumber;
1136 jsle:record "ACT_SETOBJVAR_LOCAL"
1141 [2] = "NUMOP_VARIANT";
1142 [3] = "NUMOP_VARIANT";
1144 html = [[Запомнить в объекте «%C(1)%» в слот №%C(2)% <b>приватное</b> значение %C(3)%]];
1146 handler = node_children_placeholders_filler [[self:setobjvar_local($(1), $(2), $(3))]];
1149 jsle:record "NUMOP_GETOBJVAR_LOCAL"
1154 [2] = "NUMOP_VARIANT";
1156 html = [[вспомнить из объекта «%C(1)%» из слота №%C(2)% <b>приватное</b> значение]];
1158 handler = node_children_placeholders_filler [[self:getobjvar_local($(1), $(2))]];
1161 jsle:record "ACT_SETOBJVAR_GLOBAL"
1166 [2] = "NUMOP_VARIANT";
1167 [3] = "NUMOP_VARIANT";
1169 html = [[Запомнить в объекте %C(1)% в слот №%C(2)% <b>публичное</b> значение %C(3)%]];
1171 handler = node_children_placeholders_filler [[self:setobjvar_global($(1), $(2), $(3))]];
1174 jsle:record "NUMOP_GETOBJVAR_GLOBAL"
1179 [2] = "NUMOP_VARIANT";
1181 html = [[вспомнить из объекта %C(1)% из слота №%C(2)% <b>публичное</b> значение]];
1183 handler = node_children_placeholders_filler [[self:getobjvar_global($(1), $(2))]];
1186 jsle:record "ACT_REMOVE_OVERTIMES"
1190 [1] = "OT_EFFECT_TARGET";
1192 html = [[Снять все эффекты, наложенные %C(1)%]];
1194 handler = node_children_placeholders_filler [[self:remove_overtime_effects($(1))]];
1197 jsle:enum "GAME_MODES"
1201 { [GMF.ALL] = [[любой]] };
1202 { [GMF.DUEL] = [[дуэль]] };
1203 { [GMF.SINGLE] = [[одиночная игра]] };
1205 html = [[%VALUE()%]];
1207 handler = get_value_tonumber;
1210 jsle:record "BOOLOP_IS_GAME_IN_MODE"
1216 html = [[игровой режим «%C(1)%» включён]];
1218 handler = node_children_placeholders_filler [[self:is_game_in_mode($(1))]];
1221 jsle:record "ACT_SETOBJVAR_OT"
1225 [1] = "NUMOP_VARIANT";
1226 [2] = "NUMOP_VARIANT";
1228 html = [[Запомнить в текущем овертайме в слот №%C(1)% значение %C(2)%]];
1230 handler = node_children_placeholders_filler [[self:setobjvar_ot($(1), $(2))]];
1233 jsle:record "NUMOP_GETOBJVAR_OT"
1237 [1] = "NUMOP_VARIANT";
1239 html = [[Вспомнить из текущего овертайма из слота №%C(1)%]];
1241 handler = node_children_placeholders_filler [[self:getobjvar_ot($(1))]];
1250 jsle:literal "ACT_CRASH_GAME"
1252 html = [[<span style="color:red"><b>УРОНИТЬ</b> игру (только для теста)<span>]];
1253 checker = function(self, node)
1254 if common_get_config().crashers_enabled == true then
1255 errr("WARNING: ACT_CRASH_GAME CRASHER IS ON")
1259 errr("DETECTED ATTEMPT TO UPLOAD CRASHERS (SCHEMA)")
1260 return false, "crashers are disabled in config"
1262 handler = invariant [[self:crash_game()]];
1265 jsle:literal "NUMOP_CRASH_GAME"
1267 html = [[<span style="color:red"><b>УРОНИТЬ</b> игру (только для теста)<span>]];
1268 checker = function(self, node)
1269 if common_get_config().crashers_enabled == true then
1270 errr("WARNING: NUMOP_CRASH_GAME CRASHER IS ON")
1274 errr("DETECTED ATTEMPT TO UPLOAD CRASHERS (SCHEMA)")
1275 return false, "crashers are disabled in config"
1277 handler = invariant [[(self:crash_game() or 0)]];
1285 define_schema = define_schema;