Перейти к содержанию

Сообщения от Скрипты

Аватар пользователя
Азгалор.
for e, enemy in enemy_creatures do
for f, friend in friend_creatures do
if GetHeroCreatures(heroes, enemy) > 0 and GetHeroCreatures(heroes, enemy) <= 99 then
reputation = reputation - 1
sleep(1)
elseif GetHeroCreatures(heroes, enemy) >= 100 then
reputation = reputation - 2
sleep(1)
elseif GetHeroCreatures(heroes, friend) > 0 then
reputation = reputation + 1
end
end
end

Банально пройдёмся вместе со счётчиком. Первая итерация цикла e,enemy in enemy creatures. В ней - цикл на 21 прокрут (внутренний цикл f, firend in friend_creatures). Проверка наличия злых существ идёт внутри внутреннего цикл, простите за тавтологию. А значит при наличии 1 существа из "злых" он проведёт одну и ту же проверку 21 раз, пока не закончится внутренний цикл! То есть за 1 злое существо списывается аж 21 репутация smile Отсюда и другие приколы. Решение - циклы должны быть не вложенными, а отдельными (думаю, вам не нужно показывать, как их разделить; проверка злых существ в злом цикле for, проверка хороших - в хорошем цикле for.

Есть и более элегантное решение. Первое. Создадим глобальную таблицу "репутация", через которую будем вести привязку всех переменных и таблиц. Все id внести в одну таблицу с именованными полями:

reputation = {}
reputation.heroes = {'Валерия', 'Ласло'}
reputation.value = 1--Значение репутации
reputation.creatures = {
[1] = {id = 1, mode = 'good', rep_decline = {['<100'] = +1, ['>100'] = +2},},
[2] = {id = 2, mode = 'good', rep_decline = {['<100'] = +1, ['>100'] = +2},},
[3] = {id = 101, mode = 'bad', rep_decline = {['<100'] = -1, ['>100'] = -2},},
[4] = {id = 114, mode = 'bad', rep_decline = {['<100'] = -1, ['>100'] = -2},},
[5] = {id = 98, mode = 'bad', rep_decline = {['<100'] = -1, ['>100'] = -2},},
--И так далее
}



Так мы сможем варьировать влияние на репутацию для каждого отдельного существа.

function reputation.condition()
for n, hero in reputation.heroes do
for key, cr_properties in reputation.creatures do
if GetHeroCreatures(hero, cr_properties.id)>0 and GetHeroCreatures(hero, cr_properties.id)<100 then
reputation.value = reputation.value + cr_properties.rep_decline['<100']
elseif GetHeroCreatures(hero, cr_properties.id)>100 then
reputation.value = reputation.value + cr_properties.rep_decline['>100']
end
end
end

При таком решении даже не нужно поле "хороший/плохой", но для наглядности пусть присутствует. Соответственно, через глоабльную таблицу reputation создаём таблицу влияния на репутацию посещения зданий (таким же Макаром); пишем функцию для триггеров касания всех этих объектов. Ключами в полях таблицы здания будут не 1,2,3,итд, как выше, а имена зданий.

reputation.buildings = {
['ИмяЗдания1'] = {rep_decline = +100},
['ИмяЗдания2'] = {rep_decline = -200},
['ИмяЗдания3'] = {rep_decline = +55},
--И так далее
}

function reputation.buildings_visit(hero,obj)
reputation.value = reputation.value + reputation.buildings[obj].rep_decline
end

function reputation.building_triggers()
for name, prop in reputation.buildings do
Trigger(OBJECT_TOUCH_TRIGGER, name, 'reputation.buildings_visit')
end
end

--Не забудем вызвать "навешивание" триггеров. Оно будет идти автоматически для всех объектов, указанных в таблице
reputation.building_triggers()

Такие глобальные таблицы нужны, чтобы при больших объёмов скриптов не пересекались названия переменных. При желании, можете абсолютно везде выше стереть строчки reputation. и всё будет работать.

С уважением, }{0TT@6bI4
_________________
Группа картостроителей
Там ответы на вопросы, руководства, гайды и прочее
Discord-сервер "Герои 5: S.T.A.L.K.E.R"
Сервер по модификации "Герои 5: S.T.A.L.K.E.R"
_________________
В ответ пользователю }{0TT@6bI4
Аватар пользователя
Я бы хотел спросить есть файл там где есть id существ Повелители орды?
Аватар пользователя
Alinksolo, откройте ПапкаИгры/data/data.pak/, скопируйте себе куда-либо файл types.xml (лежит вне папок, просто в архиве). Откройте его и нажмите Ctrl + F, ищите CREATURE_PEASANT. Первое совпадение пропускаем, а после второго видим блок CREATURE_PEASANT и внизу 1. Все, мотайте колесиком вниз до нужных вам существ, id будет совпадать с цифрой под именем CREATURE.

Ну или в редакторе скриптов нажмите Ctrl + Space и промотайте список до айди существ, желтым будут подписаны русские имена.
С уважением, }{0TT@6bI4
_________________
Группа картостроителей
Там ответы на вопросы, руководства, гайды и прочее
Discord-сервер "Герои 5: S.T.A.L.K.E.R"
Сервер по модификации "Герои 5: S.T.A.L.K.E.R"
_________________
Аватар пользователя
}{0TT@6bI4, ого! Большое спасибо :) С таблицами ранее не работал(потому как их нет в сценариях оригинальных кампаний), поэтому не знал что можно всё это дело вот так аккуратненько и красиво оформить. А так же, очень благодарен за объяснение ошибки счетчика из-за циклов for. Как знал что это плохая идея - ставить два цикла for с чеком массивов существ вместе, и ведь не ошибся) Не знаю почему сразу их не переписал, ведь под рукой был очень хороший пример в виде функции из 5 миссии за Фриду во Владыках, где мятежники переходят к игроку(а там передаются захваченные здания, города и нанятые герои). Там эти циклы тоже разделены...
Аватар пользователя
В lua в принципе можно организовать некое подобие обьекто-ориентированного программирования, но в обрезанном геройском получится вряд ли. Поэтому приходится довольстоваться глобалбными таблицами с именованными полями.
С уважением, }{0TT@6bI4
_________________
Группа картостроителей
Там ответы на вопросы, руководства, гайды и прочее
Discord-сервер "Герои 5: S.T.A.L.K.E.R"
Сервер по модификации "Герои 5: S.T.A.L.K.E.R"
_________________
}{0TT@6bI4, сорри, но опять не очень понятно).
Разве после создания CombatScript я не должна вернуть файл MapScript в окно MapScript?
Если я должна, - то увы, он не возвращается. Хотя я меняю там путь и название, но редактор всё сбрасывает, и оставляет CombatScript.
А открыв ..., я там вообще не вижу теперь MapScript в окне слева, хотя ScriptsEditor показывает, что этот файл по-прежнему есть в папке игры.
Разве не важно, какой скрипт будет прописан в окне MapScript?

И второй вопрос, - я видела в других картах, что файлы CombatScript lua и xdb лежат не внутри папки Maps, а вне её.
Зачем это люди делают, и, если это важно, как мне это сделать?
ScriptsEditor не может создать файл в моей карте вне папки. Я пробовала перепаковывать карту, вставляя файлы вручную, но ScriptsEditor начинает ругаться на ошибку, а редактор такую карту вообще не грузит.

Добавлено через 18 минут
Зы первый вопрос снят. Я сохранилась, пока игра не успела сбросить изменения, и стало всё нормально, MapScript на месте.
Спасибо.
Аватар пользователя
Тут вы правы, нужно после создания CombatScript.xdb вернуть MapScript.xdb; для этого в строчку с MapScript пропишите /Maps/SingleMissions/Имякарты/MapScript

Создавать вне корневой папки луа-файлы — просто прихоть. Лучше создавать именно в ней.
С уважением, }{0TT@6bI4
_________________
Группа картостроителей
Там ответы на вопросы, руководства, гайды и прочее
Discord-сервер "Герои 5: S.T.A.L.K.E.R"
Сервер по модификации "Герои 5: S.T.A.L.K.E.R"
_________________
В ответ пользователю }{0TT@6bI4
Всё, сил моих больше нет, ни хрена не понимаю(.

В MapScript  у меня написано:

geroy = "Raelag";
SetGameVar("Raelag", geroy);
print("ГГ назван");

SetHeroCombatScript('Raelag', "/Maps/SingleMissions/Koto_Map_New/CombatScript.xdb#xpointer(/Script)");
print("комбат скрипт запущен");

Тут, вроде, всё в порядке, консоль подтверждает.

В CombatScript у меня написано:

    geroy = GetGameVar("Raelag");
   if GetHeroName(GetAttackerHero()) == geroy then
        print("если ГГ агрессор");
        SetUnitManaPoints(GetAttackerHero(), 200);
        print("дали ману");
        sleep(1)
        UnitCastAimedSpell(GetAttackerHero(), 4);
        print("кастуем");
    end;

    if GetHeroName(GetDefenderHero()) == geroy then
    print("если ГГ защитник");
        SetUnitManaPoints(GetDefenderHero(), 200);
        print("дали ману");
        sleep(1)
        UnitCastAimedSpell(GetDefenderHero(), 4);
        print("кастуем");
    end;

И в тактическом режиме вылезает:
Value was NIL when getting global with name 'SetHeroCombatScript'.
Attempt to call a nil value.

Где ж нуль-то, когда я, вроде написала, что geroy = "Raelag"?
Хелп, люди добрые, подскажите, что тут надо писать?
Надо if GetHeroName как функцию сделать? Да, вроде, MapScriptsEditor на это ругается.



Добавлено через 5 минут
Или это, всё же, проблема с тем, что игра не видит комбат скрипт по указанному адресу?

Добавлено через 2 минуты
ЗЫ, да, я знаю, что здесь после sleep запятые пропущены. Но в скрипте они не пропущены, да до sleep дело и не доходит.
В ответ пользователю Марта
Аватар пользователя
Марта

SetGameVar("Raelag", geroy);
Это что за чудо-юдо?! Достаточно написать main_hero = 'Raelag'. SetGameVar используется для перенесения переменных из скрипта в скрипт и через миссии кампаний.
В бою имя героя легко и просто узнать функцией GetHeroName, а потому можно упростить + нужно повесить хук начала боя.
function Start()
if GetHeroName(GetAttackerHero()) == 'Raelag' then
print("если ГГ агрессор");
local mana = GetUntiManaPoints(GetAttackerHero()) --Иначе мы ни с того ни с сего оставим 200 маны игроку!
SetUnitManaPoints(GetAttackerHero(), 200);
repeat sleep(1) until GetUntiManaPoints(GetAttackerHero())==200 --Спать до тех пор, пока не начислится мана
UnitCastAimedSpell(GetAttackerHero(), 4);
SetUnitManaPoints(GetAttackerHero(), mana); --Вернём маны, сколько было!
print("кастуем");
elseif GetHeroName(GetDefenderHero()) == 'Raelag' then
print("если ГГ агрессор");
local mana = GetUntiManaPoints(GetDefenderHero()) --Иначе мы ни с того ни с сего оставим 200 маны игроку!
SetUnitManaPoints(GetDefenderHero(), 200);
repeat sleep(1) until GetUntiManaPoints(GetDefenderHero())==200 --Спать до тех пор, пока не начислится мана
UnitCastAimedSpell(GetDefenderHero(), 4);
SetUnitManaPoints(GetDefenderHero(), mana); --Вернём маны, сколько было!
print("кастуем");
end;
end

Ошибка скрипта очень странная, как будто у вас в бою выполняется ещё и MapScript: в тактическом режиме нет такой функции, а потому и выскакивает ошибка. Можете приложить оба файла скрипта? Загрузите на гугл/яндекс-диск там.

С уважением, }{0TT@6bI4
_________________
Группа картостроителей
Там ответы на вопросы, руководства, гайды и прочее
Discord-сервер "Герои 5: S.T.A.L.K.E.R"
Сервер по модификации "Герои 5: S.T.A.L.K.E.R"
_________________
В ответ пользователю }{0TT@6bI4
Давайте я попробую написать ваш скрипт, и, если ошибка сохранится, будет иметь смысл грузить.
А то я не больно-то знаю, как это сделать, но я разберусь, если будет надо.

У меня была версия, что комбат скрипт не просто так выносят за папку карты, основываясь вот на этой теме:
https://forum.heroesworld.ru/showthread. ... &page=60
https://forum.heroesworld.ru/showthread. ... &page=61
"В том то и дело, что полный путь должен быть не /Maps/SingleMissions/NewRandomMap21/CombatScript.xdb#xpointer(/Script), а /CombatScript.xdb#xpointer(/Script), то есть файл xdb не должен находиться в папке вообще"(с).

Если ошибка сохранится, может быть, в этом всё и дело.
А если нет - дело в моих косяках.
Спасибо, что вы тратите на меня время.


Добавлено через 12 минут
ЗЫ да, ошибка осталась. Пойду пытаться загрузить файлы.

Добавлено через 7 минут
Вот, вроде:
https://disk.yandex.ru/client/disk/%D0%A1%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D1%8B
Аватар пользователя
У меня как-то прекрасно работает с CombatScript'ом внутри, да и в картах по типу Наемники или Проклятый, которые я смотрел тоже 🧐

И только не говорите мне, что вы просто повторили все действия отсюда => https://forum.heroesworld.ru/showpost.ph ... ount=897

Надеюсь, вы не трогали никаких combat-common.lua? Потому что способо JonnyP хоть и работает, но есть вариант проще, а потому про вариант с изменением дефолтного скрипта можно вообще забыть.
function ReturnHeroScript(hero)
if hero == "Имя героя" then
SetHeroCombatScript(hero, "путькскрипту")
end
end

for i=1, 8 do
if GetPlayerState(i)==PLAYER_ACTIVE then
Trigger(PLAYER_ADD_HERO_TRIGGER, "ReturnHeroScript")
end
end


Вот этот скрипт банально навешивает заново комбат скрипт на героя, если его заново наняли. Удобно? Удобно.

Ну а причина переноса комбат скрипта вне архива карты там проста:
Героист создал скрипт в Maps/SingleMissions/ИмяКарты/, но упорно писал просто "/CombatScript.xdb#xpointer(/Script)"
Ну вот RedHeavenHero и посоветовал ему тогда положить файл скрипта правильно, в корень. А можно было просто написать "/Maps/SingleMissions/Имякарты/CombatScript.xdb#xpointer(/Script)"

С уважением, }{0TT@6bI4
_________________
Группа картостроителей
Там ответы на вопросы, руководства, гайды и прочее
Discord-сервер "Герои 5: S.T.A.L.K.E.R"
Сервер по модификации "Герои 5: S.T.A.L.K.E.R"
_________________
Аватар пользователя
Ссылка битая. Вы даже не умеете делиться файлами с диска? mad Загрузить => Дожидаетесь окончания загрузки => Нажимаете "Поделитсья" => Копируете ссылку.
С уважением, }{0TT@6bI4
_________________
Группа картостроителей
Там ответы на вопросы, руководства, гайды и прочее
Discord-сервер "Герои 5: S.T.A.L.K.E.R"
Сервер по модификации "Герои 5: S.T.A.L.K.E.R"
_________________
Я только что скачала по этой ссылке мои собственные файлы, так каким образом она может быть битой?
До сего дня мне не пригождалось умение делиться файлами, и я в Яндекс Диске не вижу никакого "поделиться", вижу только "создать" и "загрузить".
Или для этого надо установить Яндекс Диск?

Добавлено через 3 минуты
https://disk.yandex.ru/d/e9ITeouDU9b_NA
А если так?

Добавлено через 5 минут
Почему же, я попробовала и версию с combat-common тоже.
Но опыт показал, что в папку карты его класть бессмысленно, а если положить в папку игры, то у других персонажей перестают действовать их спецспособности.
Так что, я откатила всё назад и больше к этому делу не возвращалась.
Дефолтных файлов я не трогала, просто создала папку в Data, потом когда не пошло, её удалила.
Аватар пользователя
а можно саму карту поглядеть? точно там корректно указан путь к скрипту самой карты?
Нет войне.
Gerter, мне бы не хотелось выкладывать этот тяжеловесный недодел в сеть).
Но уверяю вас, что скрипты на данный момент там только те, которые я выложила, и их автор Хоттабыч, а не я.

Только что я сгенерила маленькую пробную карту, понавешала туда то же самое, и там такая же ошибка, - вот карта:
https://disk.yandex.ru/d/Ks0EtQTqTrSgiw

То есть, я на ней, видимо, сделала ту же самую ошибку.
Вопрос - какую.


Добавлено через 4 минуты
Ой, млин, сорри, я же там название карты не поменяла. сейчас поменяю

Добавлено через 9 минут
Поменяла, и ошибка ушла.

https://disk.yandex.ru/d/3ZK6bMV7N0S_lA

Но Раилаг что-то всё равно ничего не кастует...

Добавлено через 1 минуту
При этом мне консоль даже сообщения об ошибке не выводит, просто тишина.
Ох, что-то я делаю не то...

Добавлено через 9 минут
И я, кажется, нашла ошибку на большой карте.
Мой combat script.xdb ведёт не к combat script.lua, а к map script.lua.
Интересно, как же это так вышло. Пойду править.

Статистика

Приветствуем новейшего участника: Emil

Сейчас на сайте 6 пользователей 1346 гостей