• Уважаемые гости и новички, приветствуем Вас на нашем форуме
    Здесь вы можете найти ответы практически на все свои вопросы о серии игр «Готика» (в том числе различных модах на нее), «Ведьмак», «Ризен», «Древние свитки», «Эра дракона» и о многих других играх. Можете также узнать свежие новости о разработке новых проектов, восхититься творчеством наших форумчан, либо самим показать, что вы умеете. Ну и наконец, можете обсудить общие увлечения или просто весело пообщаться с посетителями «Таверны».

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!

Вопросы по скриптингу

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
  • Первое сообщение
  • #1
Прежде чем задавать вопросы, ознакомьтесь с документацией..
1) Читать онлайн
2) Архив с офлайн-версией(chm) во вложении
 

Вложения

  • Vam_tutor.rar
    171,6 KB · Просмотры: 574
Последнее редактирование модератором:

Myxomop

Почетный форумчанин
Регистрация
28 Май 2005
Сообщения
3.239
Благодарности
2.581
Баллы
455
jeludok,
\Story\Events\EventsTemple.d
Эти функции повешены на триггеры в миры игры с помощью Спейсера.
 

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Есть вопрос, больше теоретический:
может кто пытался разобраться с флагами у предметов?
При получении флага через
getmeleq = Npc_GetEquippedMeleeWeapon(hero);
getmeleq.flags
на Посох кольца возвращает значение 1082261506, прописан только flags = ITEM_2HD_AXE;, его значение 131072.
Т.е. вариант определения типа оружия по сравнению флагов if(getmeleq.flags == ITEM_2HD_AXE) не проходит.
Выход то я нашел, но интересно узнать что и как считает движок по флагам.
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
450
Благодарности
266
Баллы
230
const int ITEM_2HD_AXE = 1 << 17;//логический сдвиг влево операнда1 на величину операнда2.

Т.е. это не обычная константа, а это сдвиг в памяти процесса игры и значения получаются всегда разные, т.к. память не статична, постоянно что-то записывается туда и удаляется. Это ближе к языку си++, си Шарп, поищи в поисковике про этот сдвиг в языках программирования, мб лучше разберёшься.

Для справки:
1.3.8. Операции сдвига

Операции сдвига осуществляют смещение операнда влево (<<) или вправо (>>) на число битов, задаваемое вторым операндом. Оба операнда должны быть целыми величинами. Выполняются обычные арифметические преобразования. При сдвиге влево правые освобождающиеся биты устанавливаются в нуль. При сдвиге вправо метод заполнения освобождающихся левых битов зависит от типа первого операнда. Если тип unsigned, то свободные левые биты устанавливаются в нуль. В противном случае они заполняются копией знакового бита. Результат операции сдвига не определен, если второй операнд отрицательный.
Преобразования, выполненные операциями сдвига, не обеспечивают обработку ситуаций переполнения и потери значимости. Информация теряется, если результат операции сдвига не может быть представлен типом первого операнда, после преобразования.
Отметим, что сдвиг влево соответствует умножению первого операнда на степень числа 2, равную второму операнду, а сдвиг вправо соответствует делению первого операнда на 2 в степени, равной второму операнду.
const int ITEM_2HD_AXE = 1 << 17;
Поэтому 2^17 = 131072
Это касается константы.

Мдее.. возможно, что здесь замешаны свойства нпс, носящего(не одето, лежит в инвентаре) или инициализирующего рассматриваемый предмет. Как-то статически непонятно сделано*???*
Есть тест-таблица с данными, но всё равно надо разбираться откуда берутся значения флагов...

Посту ниже:
Т.е. это не обычная константа, а это сдвиг в памяти процесса игры и значения получаются всегда разные, т.к. память не статична, постоянно что-то записывается туда и удаляется.

Это писал тогда, когда ещё не разобрался как следует, а лишь предположил, что так происходит. Это всё видно по excel-файлу, выложенному уже много позже после этого бреда.

Мда.. всё-таки интересно было бы посмотреть откуда берутся эти загадочные числа высокого порядка(1082261506) и от чего они зависят(Конкретно!, а не в общем виде). А так, можно воспользоваться побитовой операцией И.

Сделал бы поправку(т.к. некоторым юзерам будет не очень понятно условие):

if((getmeleq.flags & ITEM_2HD_AXE) == ITEM_2HD_AXE)//так норм.
...

Ещё, если уж совсем-совсем хочется разобраться как это работает, то надо почитать про побитовые логические операции(в языках си, ассемблер и др., там просто. А не то, чтобы - работает и ладно, а чё и как?). Кому интересно как работает побитовые операции, но не можете найти инфу по этой теме, могу объяснить(обращайтесь в личку). Про это всё ясно, лично мне, но 1082261506 остаётся загадкой...

Если попадётся число, например, 1082196994 которое будет работать с 131072 в побитовой системе логической "И", то полетит крахом сесь скрипт, и не факт, что такого не может быть...
Проще говоря - смещение(не такое << или >>) на 1 бит в лево или вправо и ппц.
 

Вложения

  • Goth_Test.rar
    7,6 KB · Просмотры: 133

Vam

Почетный форумчанин
Регистрация
8 Июл 2008
Сообщения
255
Благодарности
1
Баллы
180
Т.е. это не обычная константа, а это сдвиг в памяти процесса игры и значения получаются всегда разные, т.к. память не статична, постоянно что-то записывается туда и удаляется. Это ближе к языку си++, си Шарп, поищи в поисковике про этот сдвиг в языках программирования, мб лучше разберёшься.
Это полный бред, значение всегда одно, все константы вычисляются компилятором на стадии создания dat файла. В данном случае 1 << 17 = 131072 в нех виде 0х20000, т.ч. это число занимает всего один бит, далее, при получении флагов в игре в этом числе присутствуют и другие биты, т.к. это битовый массив, часть из них может добавляться скриптами, а несколько служебных бит самим движком, поэтому чтобы в игре проверить, что интересующий нас флаг установлен необходимо выполнить следующее действие:
Код:
if(getmeleq.flags & ITEM_2HD_AXE)
{
       //установлен
}
else
{
       //сброшен
};
 

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Vam,
Шоколадно!
clap_cool.gif

Иногда все-таки надо смотреть описания констант и учить матчасть. :)
 

GothMass


Модостроитель
Регистрация
4 Окт 2010
Сообщения
336
Благодарности
314
Баллы
220
Скажите пожалуйста, а можно ли как нибудь сделать. Чтобы если ГГ получил одержимость и не лечиться 2 дня то ему его друзья тоже ищущими кажутся, просто на них доспехи надеты Ищущих.
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
450
Благодарности
266
Баллы
230
Инфо:
похоже на то, что B_SCIsObsessed(var C_Npc dementor) - это функция сглаза и B_ClearSCObsession(self) - это очистка эффекта сглаза, гже self - должен быть ГГ(взято из зупырька, поэтому и self, т.е. тот кто юзает).

Что делать:
Далее вводишь переменную для хранения кол-ва дней до сглаза, например,
var int ObsessedDay;

Далее вызываешь сглаз при определённых условиях, т.е. B_SCIsObsessed(var C_Npc dementor), где dementor - это инстанция Ищущего, который одарил ГГ одержимостью.
Пример вызова функции, только не в пустую конечно надо писать, а знать куда воткнуть эту строчку и тут же пишешь день сглаза:
B_SCIsObsessed(DMT_1200_Dementor);//дарим ГГ от DMT_1200_Dementor одержимость
ObsessedDay = Wld_GetDay();//получаем день одержимости
CreateInvItem(NONE_100_Xardas,ITAR_Dementor);//создаём в инвентаре друга доспех ищущего
AI_EquipArmor(NONE_100_Xardas, ITAR_Dementor);//одеваем друга в доспех Ищущего


Вот теперь скажи при каких именно условиях должна быть проверка на истечение дней со дня "заражения одержимостью"! Либо это будет при взаимодействии с кроватью, либо через таймер, либо у матраса, ой, у Ватраса, если он ещё жив, либо ещё как-то. Твои предложения?

Скорей всего при взаимодействии с кроватью...

И можно поподробней, как это все можно сделать.
Я немного исправил функции в скриптах:
path: Story\B_Content\B_ScObsession.d
path: Story\Dialog_Mobsis\SleepABit.d
Всё, что с комментариями, то добавлено.

Примечание: одержимым ГГ становится только после встречи с 2-мя и более ищущими!
Для всех друзей нужно прописывать процесс создания, одевания, удалени вещей.
 

Вложения

  • Scr_01.rar
    2 KB · Просмотры: 119

GothMass


Модостроитель
Регистрация
4 Окт 2010
Сообщения
336
Благодарности
314
Баллы
220
Скорей всего при взаимодействии с кроватью...

И можно поподробней, как это все можно сделать.
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
450
Благодарности
266
Баллы
230
Хм... "Как войти в фазу диалога с трупом?", кто-нибудь задвался таким вопросом?

При уменьшении переменной здоровья до нуля движёк Г2 переводит НПС в цикл смерти(безсознательное состояние пока не трагаем).

Вот упал НПС после боя, что делать? как с ним войти в фазу диалога?
Не просто при условии, что НПС упал на смерть, вызываем цикл диалога, а при условии, что к этому НПС обратились после смерти, как то так.

Есть интересная константа:
const int AIV_RANSACKED = 10; //Устанавливается TRUE, если труп обыскивается

Так вот, она устанавливается в TRUE, если обыскивают ГГ, в других случаях она почему-то не работала, точнее на других НПС, т.е. как было значение FALSE, так и осталось. Мб какие-нить восприятия не проинициализировались?

Есть ещё 1 способ:
ставим Здоровье у всех НПС примерно 10 000. При уменьшении, например, до 9700, НПС переводится в цикл "смертельного диалога", т.е. он как бы падает, а на самом деле он просто лежит и ждёт диалога также, как и некоторые НПС, сидящие на лавочке(предположить, что ХП бар невидимый).

Ну и осталось на закуску ещё одно мнение...
Есть цикл безсознательного состояния, в который также переводятся НПС, только у них остаётся "1 ХП". Здесь заменяем анимацию дергания и шевеления НПС на бездвижное лежание, т.е смертеподобное, НО вроде как нельзя начать диалог с НПС, который находится в безсознательном состоянии, НО можно попробовать изменить сам цикл безсозн. состояния, т.е. ZS_Unconscious_Loop().

Ваше мнение?
 

DUSTinghoFFman

Участник форума
Регистрация
24 Май 2008
Сообщения
904
Благодарности
4
Баллы
185
2Jr13San
Мне кажется, первый вариант (НПС умер) не проканает, но хотя мне просто кажется. А вот в цикле бессознательного состояния можно попробовать убрать (изменить условие для) строчку(и) Npc_SetRefuseTalk(var C_NPC npc, var int timeSec);

Всем привет, и снова у меня возник вопрос. :) Много вопросов, но я задам наиболее важный.

Долго экспериментировал, сделал наконец огненную стену для магов огня.
Только вот неприятность одна с эффектом, которую никак не могу решить...
Суть в том, что эффект как бы "поворачивается" вслед за движениями ГГ. :-\
То есть, куда бы не повернулся ГГ, плоскость эффекта всегда поворачивается вслед за ним, а это не есть гуд =(
Собственно вопрос - как сделать эффект стабильным? Чтобы он не шатался из стороны в сторону? И где нужный мне параметр - PFX или VISUALFX?
Надеюсь, понятно объяснил ::)
Ну как пример - спелл "ледяная глыба". Вертишь камеру - эффект вертится следом.

Если никак нельзя, то вся идея насмарку =(
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
450
Благодарности
266
Баллы
230
DUSTinghoFFman, ищи лучше.
К примеру искры от точильного камня. Рассмотри что на что влияет. В помощь тебе одна статейка: http://mod.worldofgothic.ru/scripting/pfx-system
 

DUSTinghoFFman

Участник форума
Регистрация
24 Май 2008
Сообщения
904
Благодарности
4
Баллы
185
2Jr13San
Да я "до дыр" эту статью дочитал... Кучу вариантов перепробовал. Часть статьи мне не понятна попросту. Некоторые термины, к примеру.
Ну если бы в статье был очевидный ответ, стал бы я спрашивать?! =(
В общем, жду ответа на вопрос, а не "посыла" =(
Но за намек спасибо, попробую глянуть. *flowers*
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
450
Благодарности
266
Баллы
230
DUSTinghoFFman, здесь прикол наверное не в том, как поворачивается изображение из которого состоит эффект, а в том, в каком виде представлено это изображение.
Попробую пояснить...
Короче есть эффекты, которые состоят из графических файлов.
Может быть сейчас я в чём-то ошибаюсь, т.к. подробно этим не увлекался, но у меня есть предположение...
Смотри, есть огонь, он состоит из мелких частиц, которые состояит из графического файла. Эти мелкие частицы направлены лицевой стороной к юзеру, ибо это изображение находится в системе с 2-мя координатными осями. Ребром картинка не повернётся, на что и собственно говоря и создана данная система. Короче, то, что тебе не нравится - это то, что изображение всегда поворачивается к юзеру.
Вот здесь вся суть:
Если ты рисуешь изображение огня как целиковое пламя, то да, это плохо смотрится и это то, что тебе не нравится. А ты попробуй сделать огонь из мелких безпредельно движущихся частиц, будет совсем другое дело. Вот в чём прикол - в том, что тебе надо делать твою огненную стену из мелких частиц, и опять же они повернутся к юзеру лицевой стороной:). Либо ищи путь в мешах...
 

DUSTinghoFFman

Участник форума
Регистрация
24 Май 2008
Сообщения
904
Благодарности
4
Баллы
185
Jr13San, вообще ВСЕ видимые эффекты состоят из графики и/или мешей. :)
Вас понял, наконец дошло что вы имеете ввиду. Это может сработать, сейчас протестирую *flowers* Только вот целиковая текстура огня гораздо красивее :-\
Насчет меша - частица (firetexture_a0.tga :D) излучается из box`а величиной 100 0 0 (х у z).
Ещё несколько вопросов появилось... ::)
1) Каков максимальный размер текста в текстовой константе? Т.е.:
const string example = "n?"; Не смог найти ответа...

2) Все пытаюсь сделать отравление как в Яктиле... Все бы хорошо, но как сделать проверку на конкретного монстра определенной инстанции? Чтобы можно было проверить из зацикленного триггера? То есть, в Яктиле каждый НПС/монстр был уникальным (своя инстанция), поэтому все хорошо. А так - получается отравил одного волка - и все, второго волка уже яд не возьмет, ибо инстанция одинакова. Есть ли путь, кроме как инстанции плодить? :D

3) В том же зацикленном триггере: задача - заставить ГГ убрать активное заклинание, если оно не выучено. Можно бы сделать так:
Код:
if(Npc_IsInFightMode(hero,FMODE_MAGIC))
	{
		var int activespell;
		activespell = Npc_GetActiveSpell(hero);
		if(PLAYER_TALENT_RUNES[activespell] != TRUE)
		{
			AI_UnreadySpell(hero);
			Print("Я не умею пользоватся этой руной!");
		};
	};

но нельзя, потому что в [] может быть лишь целое число/константа.
Есть ли другой путь? :-\ И ещё - что делает интересная функция Npc_LearnSpell? Из тутора Vam`a: // НПС npc выучил заклинание spell и может его использовать. Применения её в скриптах Готики не нашел, по крайней мере во второй. Просто бесполезна?

4) Главный вопрос, уже месяц мучаюсь - есть функция удаления рун из инвентаря убитых. Там каждая инстанция для удаления прописана вручную... В моем моде количество рун перевалило за 120, в принципе можно прописать каждую, но больно уж нудно... Можно ли хитрым способом удалить из инвентаря, допустим, все вещи с определенным флагом?
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
450
Благодарности
266
Баллы
230
1)
Пределы переменных можно узнать из курса программирования...
считаю, что размер переменной типа string до 2 млрд.
Тип string занимает 10 байт + длина строки, записанная в эту переменную, причём каждый записанный символ = 1 байту.

Тип byte принимает значения от 0 до 255 - это есть 1 байт, к сожалению такого типа в движке Готике нет, а мб и не надо(чисто для справки).
2)
Данная вставка в функцию может помочь определить попадание по цели со стороны ГГ в НПС.
func void B_AssessDamage()
{
Print("удар!");//проверка на удар
var C_Npc Quarho;
...
};

Тоже самое, только для монстров:
func void B_MM_AssessDamage()
{
Print("удар2!");//удар по нпс
var C_Npc MagGol;
...
};

Проблема тут в том, что функция не сработает при попадании в любого нпс, если удар оажется смертельным. Это можно поправить в цикле смерти или безсознательного состояния...

Как отследить попадание по ГГ с минимальной правкой скриптов я не знаю, могу лишь сказать предположение как можно сделать.
Если отслеживать изменение hero.attribute[ATR_HITPOINTS], то можно делать выводы по попаданиям со стороны врага в цикле атаки. Но опять же, не факт что здоровье ГГ обязательно изменится на 1 и больше, враг может попасть, но урон мб такими маленьким, что при рассчёте по броне, урон округлится до 0. Поэтому тут нужно всё обдумывать. Нельзя делать так, чтобы ГГ мог заражать цели ядом, а цели не могли заражать его своим оружием, пропитанным ядом.
Также нужно разделять оружие по типу дальнего радиуса поражения и ближнего. Тут тоже надо ставить проверки.
3)
Можно сделать не обязательно через таймер. Можно попробовать сделать так:
ГГ достал свиток/руну в руку, а когда начёт колдовать, выводишь сообщение: "Я не знаю как это применить" или лучше с голосом, а то эти сообщения плохо смотрятся(лично моё мнение). ГГ пожимает плечами(анимация аналогичная "не умению" вскрывать отмычками). Вот такая картина.

Ты путаешь изготовление с использованием.
А так могу сказать - пиши миниобрабатывающую функцию для каждого заклинания примерно так:
func int ItLearnSpell(var int spl)
{
if (spl == 0)
{
return PLAYER_TALENT_RUNES[SPL_PalLight];
}
else if (spl == 1)
{
return PLAYER_TALENT_RUNES[SPL_PalLightHeal];
}
...
return -1;
};

Можно ещё записывать 0 или 1 в неиспользуемые переменные в инстанции рун, а потом обращаться к ним и делать вывод по свойствам.
4)
Не тестировал этот цикл, попробуй, мб у тебя что-то получится:
func void ZS_ClearRunes()
{
PrintScreen ("Вход в функцию", -1, -1, "font_old_20_white.tga", 3);
};
func int ZS_ClearRunes_Loop()
{
var int i;//счётчик на ID
if (Npc_GetInvItemBySlot(self,INV_RUNE,1) != 0)//если есть руны в первом слоте
{
Npc_GetInvItem(self,i);//инициализируем глобальную переменную item по ID.
if((item.flags & ITEM_KAT_RUNE) == ITEM_KAT_RUNE)//если вещь - это руна
{
Npc_RemoveInvItems(self,i,Npc_HasItems(self,i));//удаляем все руны данного типа
};
i += 1;//увеличиваем счётчик
}
else//если нету рун в инвентаре нпс self
{
return LOOP_END;
};

return LOOP_CONTINUE;
};
func void ZS_ClearRunes_End()
{
};

Сначала попробуй удалить вещи из инвентаря поставив нпс с вещами в цикл.
#0
Что на счёт огненной стены скажешь? Да, если что-то непонятно, пиши.

Кстати, пока копался в скриптах, решил свой вопрос про диалог с мёртвым нпс. Как всегда сам задаю и сам же отвечаю:D

Не терпелось мне посмотреть на работу того, что я написал. Действительно, инвентарь нпс очищается от всех рун. Проблема только в том, что за 1,5 секунды происходит ~ 100 интеграций цикла. Т.е. чтобы дойти до всех этих инстанций рун мне пришлось ждать несколько минут. Первая руна из инвентаря нпс была на i = 6213. У всех по разному может быть. Нужно как-то ускорить процесс поиска этих инстанций...
Попробуй разобраться статичен ли номер у инстанций рун, проверь инициализацию рун на всех нпс и ГГ. Узнай как и от чего зависит этот номер, чтобы ускорить процесс. Мб и не надо начинать с i = 0, если номер в конкретно твоём моде будет всегда один и тот же и у всех. Мне тестировать некогда, т.к. в реале делов много + учёба, поэтому чем смог, тем помог. Удачи.

На последок хотел показать тестовый скрипт с нпс...
#1
ОМГ. Не люблю читать чужие скрипты, тем более в них разбираться. Куда интереснее придумать самому;)

Помню про оружие которое бьёт молнией. Мне смешно на такие вещи:D
Да, с ID тут проблема. Действительно, у всех вызванных копий одинаковый ID номер.
Я помню тоже как-то хотел заставить толпу "зомби-копий" пойти в разные стороны. Короче хотел управлять каждой копией. Так что-то забыл, смутно разобравшись...

Не знаю, мб это так и должно быть. Вспомни про стражников у ворот. Они одинаковы и говорят все одно и то же. Прикол в том, кто первый скажет, тот и будет типа отличаться. НО для них написаны разные инстанции, хотя всё похоже. Можно сказать, что они от одного прототипа произожли, но с разныс свойством id. Поэтому нечего обижаться на то, что копии не подчиняются твоим законам.
#2
Есть ещё одна задумка..
Пример:
Стукнул бандита(или любого друго нпс, в данном примере расскажу про бандита), создал в инвентаре бандита, например 1 уникальную вещь, которая в моде не используется. Далее когда он будет в цикле атаки, то он сам у себя проверит, если ли у него эта вещь, если да, то пошёл счётчик убывания здоровья, если нет, то ничего не происходит. В конце можно удалить эту вещь из инвентаря при смерти или при заканчивании действии яда или при смерти ГГ, чтобы не было багов.

Или также можно попробовать сделать с манной, например увеличив на 1000 при заражении, и причём нужно будет поставить ещё ограничения по колдовству на счёт того, что из этой 1000 нельзя расходовать манну. Короче идёя думаю понятна.

НА крайний случий делай n НПС с разными инстанциями, где n - это максимальное кол-во НПС одного типа в одном месте. Делай так, чтобы ни одна из инстанций не могла пересечься с такой же инстанцией, но только из другой группы. В итоге получается примерно 10 инстанций для каждого вида НПС. Чтобы они не перебегали друг к другу, т.е. не преследовали долго, придумай какую-нить зону возврата. Типа, если НПС с инстанцией убежал от своих далеко и приблизился к другой группе таких же копий, то пускай говорит в догонку: "ДА иди ты, трус!. Дальше я за тобой не побегу!".
Решение найдено!
*flowers*
 

Вложения

  • Файл скрипта.rar
    1.005 байт · Просмотры: 110

DUSTinghoFFman

Участник форума
Регистрация
24 Май 2008
Сообщения
904
Благодарности
4
Баллы
185
Jr13San,
1) Супер *flowers*
2) Вопрос отпал. Сам накосячил, сам и решил :D Наконец-то яд работает на все 100%, красота ::)
3) Для каждого заклинания - больно много. Не люблю индусский код, хочется найти вариант "поизящнее". Если не найду - то и сделаю так :-\
4) Супер! Выглядит убедительно. *flowers* Буду тестировать. Когда высплюсь :D
Да, и кстати... Руны-то нужно удалять при смерти НПС... Или из диалога торговли. А там такое промедление недопустимо... :'( Буду искать способ ускорить процесс

Стену протестировал. Уже лучше, но все равно недостаточно.
За "идеал" взял вспышки лавы. (lava_outburst)
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
450
Благодарности
266
Баллы
230
Есть другой вопрос: "Как получить ссылку на НПС, который ударил ГГ или выстрелил в него? Короче того, кто нанёс урон ГГ."

HeDeDe, я уже всё нашёл, а то - это мысли вслух. Лучше подскажи как сделать то, что я пишу выше. Что ты там про аивары говорил то?

Восприятия для ГГ не работают, т.к. это игрок, а не искусственно наделённый разумом, НПС. Мне кажется дело не в восприятиях для ГГ, а в какой-то запутанный хитрости.

Урон отследить не большая проблема, проблема в том, как понять кто именно нанёс урон, потому что в бою мб не 1 враг, а несколько + могут оказаться близко к ГГ и одновременно наносить урон, но обработка произойдёт по очереди...
Мне интересно то, как бы этих ударяющих поймать в скриптах?
 

HeDeDe

Участник форума
Регистрация
17 Авг 2009
Сообщения
203
Благодарности
79
Баллы
180
Стукнул бандита(или любого друго нпс, в данном примере расскажу про бандита), создал в инвентаре бандита, например 1 уникальную вещь, которая в моде не используется. Далее когда он будет в цикле атаки, то он сам у себя проверит, если ли у него эта вещь, если да, то пошёл счётчик убывания здоровья, если нет, то ничего не происходит. В конце можно удалить эту вещь из инвентаря при смерти или при заканчивании действии яда или при смерти ГГ, чтобы не было багов.

Зачем так сложно? Можно же использовать aivar'ы…

Как получить ссылку на НПС, который ударил ГГ или выстрелил в него? Короче того, кто нанёс урон ГГ.
Интересный вопрос… Можно попробовать поставить другого НПС, отслеживающего нанесение урона ГГ. Правда у меня сейчас нет времени проверить; есть обработчик восприятия PERC_ASSESSOTHERSDAMAGE, используется, например в ZS_WatchFight/B_CheerFight

Что ты там про аивары говорил то?
Что ты конкретно имеешь в виду?
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
450
Благодарности
266
Баллы
230
Что ты конкретно имеешь в виду?

Ладно, проехали..
Серьёзно, нет смысла обсуждать то, что уже сделано. Причём не через респаун ракушки в инвентаре:D, а через B_AssessDamage(). А так, спс. за то, что зашёл в темку для обсудения.

P.S. сорр. за дбл. пст. Это из за неудобносделанного цитирования!
 

DUSTinghoFFman

Участник форума
Регистрация
24 Май 2008
Сообщения
904
Благодарности
4
Баллы
185
Тут, в теме, давненько предлагалось улучшить функцию передачи вещей. Чтобы надписи не накладывались при частом вызове.
Вроде redleha предлагал. Ну так вот, я довел до ума. Пока не тестировал, но вроде все просто и должно работать. Как протестирую, может, чего подправлю.
Вот: (там небольшая поправочка от Возвращения, ну это не важно)
Для начала вводим глобальную переменную TextDisplacement. Затем:
Код:
func int B_GiveInvItems(var C_Npc giver,var C_Npc taker,var int itemInstance,var int amount)
{
	var string concatText;
	var string itemname;
	[COLOR="Red"]TextDisplacement += 1;
	if(TextDisplacement >= 5)
	{
		TextDisplacement = 0;
	};[/COLOR]
	if(Npc_IsPlayer(giver))
	{
		if(amount > Npc_HasItems(giver,itemInstance))
		{
			return FALSE;
		};
	};
	if(amount == 0)
	{
		return TRUE;
	};
	Npc_RemoveInvItems(giver,itemInstance,amount);
	CreateInvItems(taker,itemInstance,amount);
	itemname = item.name;
	if(Npc_IsPlayer(giver))
	{
		if(itemInstance == ItMi_Gold)
		{
			concatText = ConcatStrings(IntToString(amount),PRINT_GoldGegeben);
			AI_PrintScreen(concatText,-1,YPOS_GoldGiven[COLOR="Red"]+TextDisplacement[/COLOR],FONT_ScreenSmall,2);
		}
		else
		{
			concatText = ConcatStrings(b_formgivestring(giver,amount)," (");
			concatText = ConcatStrings(concatText,itemname);
			concatText = ConcatStrings(concatText,").");
			AI_PrintScreen(concatText,-1,YPOS_ItemGiven[COLOR="Red"]+TextDisplacement[/COLOR],FONT_ScreenSmall,2);
		};
	}
	else if(Npc_IsPlayer(taker))
	{
		if(itemInstance == ItMi_Gold)
		{
			concatText = ConcatStrings(IntToString(amount),PRINT_GoldErhalten);
			AI_PrintScreen(concatText,-1,YPOS_GoldTaken[COLOR="Red"]+TextDisplacement[/COLOR],FONT_ScreenSmall,2);
		}
		else if(itemInstance == itpo_xmagicdef)
		{
			concatText = ConcatStrings(PRINT__ERHALTEN,"напиток защиты от магии.");
			AI_PrintScreen(concatText,-1,YPOS_ItemTaken[COLOR="Red"]+TextDisplacement[/COLOR],FONT_ScreenSmall,2);
		}
		else
		{
			concatText = ConcatStrings(b_formgivestring(giver,amount)," (");
			concatText = ConcatStrings(concatText,itemname);
			concatText = ConcatStrings(concatText,").");
			AI_PrintScreen(concatText,-1,YPOS_ItemTaken[COLOR="Red"]+TextDisplacement[/COLOR],FONT_ScreenSmall,2);
		};
	};
	return TRUE;
};
Остается подправить константы позиций вывода надписей на экран, т.е. YPOS_ItemTaken и т.д., т.к. при первом же вызове новая переменная получит +=1.
Вроде все.

Ещё, может кому понадобится, функция отображения раздела дневника, куда ведется запись. (Переработанная B_LogEntry)
Код:
func void B_LogEntry(var string topic,var string entry)
{
	[COLOR="Red"]TextDisplacement += 1;
	if(TextDisplacement >= 3)
	{
		TextDisplacement = 0;
	};[/COLOR]
	Log_AddEntry(topic,entry);
	[COLOR="Red"]var string topictext;
	topictext = ConcatStrings("Новая запись в разделе -",topic);
	topictext = ConcatStrings(topictext,"-");[/COLOR]
	PrintScreen(PRINT_NewLogEntry,-1,YPOS_LOGENTRY[COLOR="Red"]+TextDisplacement[/COLOR],FONT_ScreenSmall,2);
	PrintScreen(topictext,-1,YPOS_TOPICTEXT[COLOR="Red"]+TextDisplacement[/COLOR],FONT_ScreenSmall,2);
	Snd_Play("LogEntry");
};

Даже если я где скосячил, по аналогии умная голова исправит что нужно *flowers*
 
Сверху Снизу