-- Здесь мы настраиваем парсер. local mrd = require "morph/mrd" mp.msg.SCENE = "{#Me} {#plural/находишься,находитесь} {#if_has/#here,supporter,на,в} {#here/пр,2}."; mp.msg.Exam = "{#Me} не {#g/видишь,видите} {#vo/{#first/пр}} ничего необычного."; mp.msg.LookUnder.NOTHING = "{#Me} не {#g/находишь,находите} под {#first/тв} ничего интересного." mp.msg.Enter.INV = "Нельзя зайти в то, что {#me} {#g/держишь,держите} в руках." mp.msg.Open.OPEN = "{#Me} {#g/открываешь,открываете} {#first/вн}." mp.msg.Open.CLOSE = "{#Me} {#g/закрываешь,закрываете} {#first/вн}." mp.msg.Take.HAVE = "У {#you/вн} и так {#firstit} уже есть." mp.msg.Take.SELF = "{#Me} есть у {#you/рд}." mp.msg.Drop.SELF = "У {#you/рд} не хватит ловкости." mp.msg.Insert.INSERT = "{#Me} {#g/кладёшь,кладёте} {#first/вн} в {#second/вн}." mp.msg.PutOn.PUTON = "{#Me} {#g/кладёшь,кладёте} {#first/вн} на {#second/вн}." mp.msg.SwitchOn.SWITCHON = "{#Me} {#g/включаешь,включаете} {#first/вн}." mp.msg.SwitchOff.SWITCHOFF = "{#Me} {#g/выключаешь,выключаете} {#first/вн}." mp.msg.Sing.SING = "Это лучше оставить оперным певцам." mp.msg.Smell.SMELL = "Запах очень забытых вещей." mp.msg.Smell.SMELL2 = "Не {#g/волнуйся,волнуйтесь}, у {#you/рд} не пропало чувство запаха. Просто это ничем особенным не пахнет." mp.msg.Sleep.SLEEP = "Не спится." mp.msg.Jump.JUMP = "Прыг-скок. Не помогает." mp.msg.Consult.CONSULT = "{#Me} не {#g/находишь,находите} ничего подходящего." function split(s, sep) if sep == nil then sep = "," end local t={} for str in string.gmatch(s, "([^"..sep.."]+)") do table.insert(t, str) end return t end local function istable(t) return type(t) == 'table' end -- "Ты/вы" в разных падежах: им, род, дат, вин, твор, пред. function mp.shortcut.you(case) if case == nil or case == '' then case = 'им' end if case == 'им' then if pl.plural then return 'вы' end return 'ты' end if case == 'род' or case == 'рд' then if pl.plural then return 'вас' end return 'тебя' end if case == 'дат' or case == 'дт' then if pl.plural then return 'вам' end return 'тебе' end if case == 'вин' or case == 'вн' then if pl.plural then return 'вас' end return 'тебя' end if case == 'твор' or case == 'тв' then if pl.plural then return 'вами' end return 'тобой' end if case == 'пред' or case == 'пр' then if pl.plural then return 'вас' end return 'тебе' end return 'ты' end function mp.shortcut.plural(options) if not istable(options) then options = split(options) end if pl.plural then return options[2] end return options[1] end -- {#g/singlefem,singlemasc,singleother,plural} function mp.shortcut.g(options) if not istable(options) then options = split(options) end if #options == 2 then return mp.shortcut.plural(options) end if pl.plural then return options[4] end if pl.pronouns == 'fem' then return options[1] end if pl.pronouns == 'masc' then return options[2] end if pl.pronouns == 'other' then return options[3] end return options[1] end Verb { "#Shoot", 'стрел/ять,вырез/ать', -- дань удобству - можно опустить предлог '~ {noun}/вн,scene : LetterShoot', '~ в|во {noun}/вн,scene : LetterShoot', '~ из {noun}/рд в|во {noun}/вн,scene : LetterShoot', '~ из {noun}/тв,scene : WrongShoot', } function HasChar(str, skipc) if type(str) ~= 'string' then return false end return (string.find(str, skipc) ~= nil) end function StrCut(str, skipc) if type(str) ~= 'string' then return str end return str:gsub(skipc, '') end function mp:WrongShoot(w) return 'Правильная команда: стрелять (во что-то)'; end function mp:LetterShoot(w) if not pl:have('letterremover') then return 'Нечем.'; end if (w:has 'animate') then return 'Вырезатель не работает на живых.'; end if (w:has 'essential') then return 'Это слишком полезная вещь, чтобы её вырезать.'; end local letter = _('letterremover').letter; local lcaseletter = mrd.lang.lower(letter); if w.canonical == nil or w.canonical == '' then w.canonical = w.word end if not HasChar(w.canonical, lcaseletter) then return 'Вырезатель настроен на букву '..letter..', которой нет в слове «'..w.canonical..'».'; end local newCanonical = StrCut(w.canonical, lcaseletter); local newTarget = lookup(newCanonical); if not newTarget then -- продолжаем поиск полным перебором std.for_each_obj(function(v) if v.canonical == newCanonical then newTarget = v return; end end) end if newTarget then w:remove(); put(newTarget, here()); pn('Вы стреляете в '.. w:noun'вн' ..',и это вырезается в '..newCanonical..'.'); if newTarget.oncreate ~= nil then newTarget.oncreate() end return; end return 'Вы стреляете в '.. w:noun'вн' ..' и это мигает в слабом тумане букв «'..newCanonical..'», но затем возвращается в прежнее состояние.'; end Verb { "#Set", 'установ/ить,выстав/ить', -- см. проблему #3 - я не хочу определять ещё 33*4 вариации --'~ вырезатель на А: LetterSetA', --'~ вырезатель на а: LetterSetA', --'~ а на вырезателе: LetterSetA', --'~ А на вырезателе: LetterSetA', '~ А: LetterSet1', '~ Б: LetterSet2', '~ В: LetterSet3', '~ Г: LetterSet4', '~ Д: LetterSet5', '~ Е: LetterSet6', '~ Ё: LetterSet7', '~ Ж: LetterSet8', '~ З: LetterSet9', '~ И: LetterSet10', '~ Й: LetterSet11', '~ К: LetterSet12', '~ Л: LetterSet13', '~ М: LetterSet14', '~ Н: LetterSet15', '~ О: LetterSet16', '~ П: LetterSet17', '~ Р: LetterSet18', '~ С: LetterSet19', '~ Т: LetterSet20', '~ У: LetterSet21', '~ Ф: LetterSet22', '~ Х: LetterSet23', '~ Ц: LetterSet24', '~ Ч: LetterSet25', '~ Ш: LetterSet26', '~ Щ: LetterSet27', '~ Ъ: LetterSet28', '~ Ы: LetterSet29', '~ Ь: LetterSet30', '~ Э: LetterSet31', '~ Ю: LetterSet32', '~ Я: LetterSet33', } function mp:LetterSet(w) if not pl:have('letterremover') then return 'Нечем.'; end if type(w) ~= 'string' then return 'Вырезатель можно установить только на букву русского алфавита.'; end --if string.len(w) > 1 then -- return 'Вырезатель можно установить только на одну букву.'; --end local letter = _('letterremover').letter; if letter ~= w then _('letterremover').letter = w return 'Вырезатель будет вынимать букву '..w..'.'; end return 'Вырезатель уже работает на частоте буквы '..w; end function mp:LetterSet1() return mp:LetterSet('А') end function mp:LetterSet2() return mp:LetterSet('Б') end function mp:LetterSet3() return mp:LetterSet('В') end function mp:LetterSet4() return mp:LetterSet('Г') end function mp:LetterSet5() return mp:LetterSet('Д') end function mp:LetterSet6() return mp:LetterSet('Е') end function mp:LetterSet7() return mp:LetterSet('Ё') end function mp:LetterSet8() return mp:LetterSet('Ж') end function mp:LetterSet9() return mp:LetterSet('З') end function mp:LetterSet10() return mp:LetterSet('И') end function mp:LetterSet11() return mp:LetterSet('Й') end function mp:LetterSet12() return mp:LetterSet('К') end function mp:LetterSet13() return mp:LetterSet('Л') end function mp:LetterSet14() return mp:LetterSet('М') end function mp:LetterSet15() return mp:LetterSet('Н') end function mp:LetterSet16() return mp:LetterSet('О') end function mp:LetterSet17() return mp:LetterSet('П') end function mp:LetterSet18() return mp:LetterSet('Р') end function mp:LetterSet19() return mp:LetterSet('С') end function mp:LetterSet20() return mp:LetterSet('Т') end function mp:LetterSet21() return mp:LetterSet('У') end function mp:LetterSet22() return mp:LetterSet('Ф') end function mp:LetterSet23() return mp:LetterSet('Х') end function mp:LetterSet24() return mp:LetterSet('Ц') end function mp:LetterSet25() return mp:LetterSet('Ч') end function mp:LetterSet26() return mp:LetterSet('Ш') end function mp:LetterSet27() return mp:LetterSet('Щ') end function mp:LetterSet28() return mp:LetterSet('Ъ') end function mp:LetterSet29() return mp:LetterSet('Ы') end function mp:LetterSet30() return mp:LetterSet('Ь') end function mp:LetterSet31() return mp:LetterSet('Э') end function mp:LetterSet32() return mp:LetterSet('Ю') end function mp:LetterSet33() return mp:LetterSet('Я') end