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

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

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

MaGoth

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

Вложения

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

Lingviston

Участник форума
Регистрация
10 Май 2010
Сообщения
14
Благодарности
0
Баллы
150
Да, я читал тутор Вама. Значит каким-то образом выход из ф-ии произощел раньше, чем я прописал команду :( Спасибо.
 

Redds

Участник форума
Регистрация
15 Сен 2009
Сообщения
52
Благодарности
0
Баллы
155
Re: Технические вопросы.

У меня Готика 2 без аддона, и я не могу найти папку NPC. В папке Content только Cutscene и все, а в ней файл .bin и .csl :eek:
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
Re: Технические вопросы.

Redds, Для чего тебе нужна папка Нпс, это первое.
Второе, что твой вопрос делает в этой теме, если это относится к модостроению, в части скриптинга?!
 

Redds

Участник форума
Регистрация
15 Сен 2009
Сообщения
52
Благодарности
0
Баллы
155
Re: Технические вопросы.

MaGoth, 1. папка мне нужна чтобы изменить данные некоторых неписей через GS :)
2. я думаю, если бы вопрос был конкретно о скриптах, то туда. Но отсутствие какой либо папки это техническая пролема :)
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
Re: Технические вопросы.

Redds, чтобы эта папка появилась нужно декомпилировать файлы Gothic.dat и Ou.bin программой ГотикСоурсер 3.14.
Как ей пользоваться расписано здесь:
http://mod.worldofgothic.ru/programs/gothic-sourcer/manual

Зы. Посты перенес в тему Скриптинга...
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
450
Благодарности
266
Баллы
230
Извините, что вмешиваюсь в разговор, но скрипты от оригинальной Готики 2 компилруются с ошибками. Redds, как? скомпилировал скрипты? Ответ пиши в личку(если хочешь, можешь не отвечать).
 

Lingviston

Участник форума
Регистрация
10 Май 2010
Сообщения
14
Благодарности
0
Баллы
150
ukur
по поводу ф-ий экипировки оружия. Как внутри этой ф-ии получить ссылку что ли на экипируемое оружие? Вот например я хочу, чтобы в момент экипировки лука его амуниция изменялась на огненные стрелы.
 

HeDeDe

Участник форума
Регистрация
17 Авг 2009
Сообщения
203
Благодарности
79
Баллы
180
по поводу ф-ий экипировки оружия. Как внутри этой ф-ии получить ссылку что ли на экипируемое оружие? Вот например я хочу, чтобы в момент экипировки лука его амуниция изменялась на огненные стрелы.

Попробуй это:

Npc_GetEquippedMeleeWeapon(self);
Npc_GetEquippedRangedWeapon(self);
 

Lingviston

Участник форума
Регистрация
10 Май 2010
Сообщения
14
Благодарности
0
Баллы
150
Не-а, пробовал. Ведь ф-ия экипировки оружия вызывается в момент, когда оружие, по идее, еще не является экипированным. Есть еще варианты?

Казалось бы ф-ия - член класса, а доступа к полям не имеет :(
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
450
Благодарности
266
Баллы
230
Lingviston, я бы не советовал тебе писать адресацию проблем именно ukur'у, потому что на твой вопрос просто из за принципа найдётся мало отвечающих.
Вот, посмотри пример лука:

instance ItRw_Bow_H_02(C_Item)
{
name = "Дубовый лук";
mainflag = ITEM_KAT_FF;
flags = ITEM_BOW;
material = MAT_WOOD;
value = Value_Eichenbogen;
damageTotal = Damage_Eichenbogen;
damagetype = DAM_POINT;
munition = ItRw_Arrow;
cond_atr[2] = ATR_DEXTERITY;
cond_value[2] = Condition_Eichenbogen;
visual = "ItRw_Bow_H_02.mms";
on_equip = Equip_ItRw_Bow_H_02;
on_unequip = UnEquip_ItRw_Bow_H_02;
description = name;
text[2] = NAME_Damage;
count[2] = damageTotal;
text[3] = NAME_Dex_needed;
count[3] = cond_value[2];
text[5] = NAME_Value;
count[5] = value;
};
func void Equip_ItRw_Bow_H_02()
{
ItRw_Bow_H_02.munition = ItRw_Addon_FireArrow;
};

Здесь тупо динамически меняются заряды для лука. Если сохранить игру, то заряды(динамически изменённые) не будут для этого лука активными. Поэтому целесообразней использовать переменную для хранения ссылки на заряды для лука.
 

Lingviston

Участник форума
Регистрация
10 Май 2010
Сообщения
14
Благодарности
0
Баллы
150
А, черт, я так тоже хотел сделать, а потом решил, что будет удобнее описать 1 ф-ию для всех луков. Так а насчет переменной, это я должен объявить глобальную переменную от которой будет зависеть заряд и внутри каждого лука заменить стандартный заряд на эту переменную или имеется в виду хранить заряд в глобальной переменной, а в ф-ии экипировки заменять заряд на значение из этой переменно?
Еще, если я экипируюсь например Коротким луком, у него меняется амуниция, так вот если непись будет экипирована им же, у него тоже будет нестандартная амуниция?
По крайней мере если для каждого лука сделать ф-ию экипировки, то можно сделать проверку на self - ГГ.
 

Мільтен

Участник форума
Регистрация
27 Июн 2008
Сообщения
862
Благодарности
427
Баллы
265
Народ, может подскажет кто, почему не работает:

Код:
    if(Npc_IsDead(SPI_5080_hunter))
    {
    действие
    }

Мне сразу возвращается значение TRUE и действия выполняются, даже если непись жив.

И еще пару вопросов:

1) Можно ли проиграть pfx эффект на вейпоинте?
2) Как заставить непися атаковать меня и драться на смерть? Я ставлю вражеские отношения гильдий, так там еще добивать надо. B_Attack также надо добивать. AI_ATTACK не работает вообще. Можно в скрипте непися указать вражеское отношение к ГГ? Сразу же, вначале игры.
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
450
Благодарности
266
Баллы
230
Так а насчет переменной, это я должен объявить глобальную переменную от которой будет зависеть заряд и внутри каждого лука заменить стандартный заряд на эту переменную или имеется в виду хранить заряд в глобальной переменной, а в ф-ии экипировки заменять заряд на значение из этой переменно?
Проще будет показать, но этот пример пока не работает. Вот:
var C_ITEM Mn_ItRw_Bow_H_02;

instance ItRw_Bow_H_02(C_Item)
{
...
munition = Mn_ItRw_Bow_H_02;
...
on_equip = Equip_ItRw_Bow_H_02;
on_unequip = UnEquip_ItRw_Bow_H_02;
...
};

Еще, если я экипируюсь например Коротким луком, у него меняется амуниция, так вот если непись будет экипирована им же, у него тоже будет нестандартная амуниция?
А как же? Конечно сменится. Ведь лук в игре - он для всех одинаковый. Значит и ф-ции для все одинаковые. Можно наставить разных условий. Надо просто подумать головой.

Народ, может подскажет кто, почему не работает:

Код:
    if(Npc_IsDead(SPI_5080_hunter))
    {
    действие
    }

Мільтен, вот так будет правильней:
Код:
if(Npc_IsDead(SPI_5080_hunter) > 0) //если NPC мёртв
    {
    действие
    }
1) Можно ли проиграть pfx эффект на вейпоинте?
Я думаю тебе надо пошатить в Spacer'e.
2) Как заставить непися атаковать меня и драться на смерть? Я ставлю вражеские отношения гильдий, так там еще добивать надо. B_Attack также надо добивать. AI_ATTACK не работает вообще. Можно в скрипте непися указать вражеское отношение к ГГ? Сразу же, вначале игры.
Это дело можно сэмулировать с анимациями и т.д. Но попробуй нати такую ф-цию - когда ГГ убивает человека из города, стражи бегут к ГГ, убивают его и закалывают!
 

Друид

Участник форума
Регистрация
21 Ноя 2009
Сообщения
1.170
Благодарности
398
Баллы
285
2) Как заставить непися атаковать меня и драться на смерть? Я ставлю вражеские отношения гильдий, так там еще добивать надо. B_Attack также надо добивать. AI_ATTACK не работает вообще. Можно в скрипте непися указать вражеское отношение к ГГ? Сразу же, вначале игры.
self.aivar[AIV_DropDeadAndKill] = TRUE;

if(Npc_IsDead(SPI_5080_hunter) > 0) //если NPC мёртв
if(Npc_IsDead(SPI_5080_hunter))
А по-моему, это 2 одинаковых выражения. Прокатывает и так, и эдак и даже
if(Npc_IsDead(SPI_5080_hunter) == true)
8)
Тутор Вама:
int Npc_IsDead (c_npc n0); - возвращает 1, если НПС n0 мертв, иначе – 0.
Так что, может есть двойник непися.
 

Lingviston

Участник форума
Регистрация
10 Май 2010
Сообщения
14
Благодарности
0
Баллы
150
А переменную зарядов для лука при старте игры можно проинициализировать обычными стрелами? Если нет, то чем же она будет проинициализирована при старте?
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
450
Благодарности
266
Баллы
230
Можно присвоить значение переменной в ф-ции func void Startup_[имя стартового уровня](). Только как правильно присвоить, я не знаю.
Если у тебя не получится никак присвоить значение переменной и сделать так, чтобы скрипт работал, то у меня, кажется, есть решение твоей проблемы...
Я не очень понимаю зачем тебе менять стрелы при ношении лука. Не проще ли просто поставить нужные стрелы для одного лука? Но ежели ты насмотрелся видео от мода - StrongHand и решил тоже такие возможность сделать, но по своему, то я могу тебе помочь, но у меня сейчас сессия и решение проблемы может растянуться... ;) Но могу сказать сразу - то, что я придумал - меня удивило самого. Если будет время, напишу.
Вот и написал(обновлено):
В скриптах пишем:

//Если одет один вид стрел, то стреляем ими
//Если одето много видов стрел, то стреляем теми, которые были одеты первыми,
//затем 2-ми...3-ми и т.д.
//Если стрела снята или выброшена, то происходит смещение приоритета

var int Arrow_01; //приоритет для стрелы
var int FireArrow_01; //приоритет для огненной стрелы
var int MagicArrow_01;//приоритет для магической стрелы
var int ArrNum; //кол-во видов стел
var int NumNotActive; //снятый вид стрел
var int RwCls; //0 = ничего; 1 = лук; 2 = арбалет
// Смещение(пример)
// Существует 7 видов стрел, т.е. 7 приоритетов для этих видов стрел.
// 1 2 3 4 5 6 7
// Если, например 6-ой приоритет снимается, то все меньшие приоритеты смещаются на 1 до 6-ого, тем самым освобождается место для нового приоритета
// 6 1 2 3 4 5 7
// Но так, как такой порядок неуместен для использования наивысшего приоритеда как стрел для лука, то всё это дело преобразуется в такую систему:
// 0 2 3 4 5 6 7
// т.е. 5-ка становится на место 6-ки и становится равной 6, 4-ка становитя на место 5-ки и становится равной 5 и т.д.
// ... 1-ка становится на место 2-ки и становится равной 2, а 6-ка, так как была снята, становится равной нулю и не используется для сравнения как приоритет.
// Если хочется разобраться, то всё, что происходит ниже, нужно записывать на листок бумаги или в память, потому что комментариями не объяснить.
func void Displacement()//смещение приоритета, тем самым освобождаем место для нового приоритема.
{
if (Arrow_01 < NumNotActive) && (Arrow_01 != 0)//всё, что меньше снятого приоритета - смещается до снятого приоритета
{
Arrow_01 = Arrow_01 + 1; //можно написать Arrow_01 += 1;
};
if (FireArrow_01 < NumNotActive) && (FireArrow_01 != 0)
{
FireArrow_01 = FireArrow_01 + 1;
};
if (MagicArrow_01 < NumNotActive) && (MagicArrow_01 != 0)
{
MagicArrow_01 = MagicArrow_01 + 1;
};
};

instance ItRw_Arrow_01(C_Item)
{
name = "Стрела";
mainflag = ITEM_KAT_MAGIC;
flags = ITEM_MULTI | ITEM_KAT_MAGIC;
value = Value_Pfeil;
visual = "ItRw_Arrow.3ds";
material = MAT_WOOD;
on_equip = Equip_ItRw_Arrow_01;
on_unequip = UnEquip_ItRw_Arrow_01;
description = name;
text[5] = NAME_Value;
count[5] = value;
};
func void Equip_ItRw_Arrow_01()
{
Arrow_01 = ArrNum; //записываем в переменную для хранения приоритета(для каждого вида стрел свой приоритет), выдаваемый номер приоритета от ArrNum. Изначально ArrNum = 3 - это высший приоритет(главнее всех).
ArrNum = ArrNum - 1; //Уменьшаем глобальный приоритет на единицу, дабы следующему виду стрел подготовить свободный приоритет.
};
func void UnEquip_ItRw_Arrow_01()
{
NumNotActive = Arrow_01; //записываем в переменную приоритет снятого вида стрел.
Arrow_01 = 0; //обнуляем значение приоритета данного вида стрел. Это будет говорить о том, что вещь снята.
ArrNum = ArrNum + 1; //Увеличиваем значение глобального приоритета, т.е. увеличивается количество свободных приоритетов(т.е. мест, для ношения видов стрел)
Displacement();//смещение приоритета
};
instance ItRw_FireArrow_01(C_Item)
{
name = "Огненная стрела";
mainflag = ITEM_KAT_MAGIC;
flags = ITEM_MULTI | ITEM_KAT_MAGIC;
wear = WEAR_EFFECT;
effect = "SPELLFX_FIREARROW";
value = Value_Pfeil;
visual = "ItRw_Arrow.3ds";
material = MAT_WOOD;
on_equip = Equip_ItRw_FireArrow_01;
on_unequip = UnEquip_ItRw_FireArrow_01;
description = name;
text[5] = NAME_Value;
count[5] = value;
};
func void Equip_ItRw_FireArrow_01()
{
FireArrow_01 = ArrNum;
ArrNum = ArrNum - 1;
};
func void UnEquip_ItRw_FireArrow_01()
{
NumNotActive = FireArrow_01;
FireArrow_01 = 0;
ArrNum = ArrNum + 1;
Displacement();
};
instance ItRw_MagicArrow_01(C_Item)
{
name = "Магическая стрела";
mainflag = ITEM_KAT_MAGIC;
flags = ITEM_MULTI | ITEM_KAT_MAGIC;
wear = WEAR_EFFECT;
effect = "SPELLFX_ARROW";
value = Value_Pfeil;
visual = "ItRw_Arrow.3ds";
material = MAT_WOOD;
on_equip = Equip_ItRw_MagicArrow_01;
on_unequip = UnEquip_ItRw_MagicArrow_01;
description = name;
text[5] = NAME_Value;
count[5] = value;
};
func void Equip_ItRw_MagicArrow_01()
{
MagicArrow_01 = ArrNum;
ArrNum = ArrNum - 1;
};
func void UnEquip_ItRw_MagicArrow_01()
{
NumNotActive = MagicArrow_01;
MagicArrow_01 = 0;
ArrNum = ArrNum + 1;
Displacement();
};
instance ItRw_Bow_H_03_01(C_Item)
{
name = "Военный лук";
mainflag = ITEM_KAT_FF;
flags = ITEM_BOW;
material = MAT_WOOD;
value = Value_Kriegsbogen;
damageTotal = Damage_Kriegsbogen;
damagetype = DAM_POINT;
//munition = ItRw_Arrow;
cond_atr[2] = ATR_DEXTERITY;
cond_value[2] = Condition_Kriegsbogen;
visual = "ItRw_Bow_H_03.mms";
on_equip = Equip_ItRw_Bow_H_03_01;
on_unequip = UnEquip_ItRw_Bow_H_03_01;
description = name;
text[2] = NAME_Damage;
count[2] = damageTotal;
text[3] = NAME_Dex_needed;
count[3] = cond_value[2];
text[5] = NAME_Value;
count[5] = value;
};
func void Equip_ItRw_Bow_H_03_01()
{
RwCls = 1;
};
func void UnEquip_ItRw_Bow_H_03_01()
{
RwCls = 0;
};
instance ItRw_Crossbow_M_02_01(C_Item)
{
name = "Военный арбалет";
mainflag = ITEM_KAT_FF;
flags = ITEM_CROSSBOW;
nameID = "CROSSBOW";
material = MAT_WOOD;
value = Value_Kriegsarmbrust;
damageTotal = Damage_Kriegsarmbrust;
damagetype = DAM_POINT;
munition = ItRw_Bolt;
cond_atr[2] = ATR_STRENGTH;
cond_value[2] = Condition_Kriegsarmbrust;
visual = "ItRw_Crossbow_M_02.mms";
on_equip = Equip_ItRw_Crossbow_M_02_01;
on_unequip = UnEquip_ItRw_Crossbow_M_02_01;
description = name;
text[2] = NAME_Damage;
count[2] = damageTotal;
text[3] = NAME_Str_needed;
count[3] = cond_value[2];
text[5] = NAME_Value;
count[5] = value;
};
func void Equip_ItRw_Crossbow_M_02_01()
{
RwCls = 2;
};
func void UnEquip_ItRw_Crossbow_M_02_01()
{
RwCls = 0;
};

func void AppArrow()
{
var int n; //счётчик для поиска наивысшего приоритета вида стрел
var C_Item RangedWeapon; //переменная для хранения ссылки на лук
RangedWeapon = Npc_GetEquippedRangedWeapon(hero); //записываем оружие дальнего радиуса поражения у ГГ.

if (RwCls == 1) //если одет лук
{
if (ArrNum == 3) //если стрелы не одеты
{
if (Npc_HasItems(hero, ItRw_Arrow_01) > 0) //если есть простые стрелы,
{
RangedWeapon.munition = ItRw_Arrow_01; //то одеваем их для текущего лука
}
else if (Npc_HasItems(hero, ItRw_FireArrow_01) > 0)
{
RangedWeapon.munition = ItRw_FireArrow_01;
}
else if (Npc_HasItems(hero, ItRw_MagicArrow_01) > 0)
{
RangedWeapon.munition = ItRw_MagicArrow_01;
};
}
else //если стрелы одеты, то начинаем искать наибольший приоритет вида стрел:
{
n = 0;
if (Arrow_01 > n) && (Npc_HasItems(hero,ItRw_Arrow_01) > 0)
{
n = Arrow_01; //записываем номер высшего приоритета стрел
RangedWeapon.munition = ItRw_Arrow_01; //записываем вещь как вид стрел
};
if (FireArrow_01 > n) && (Npc_HasItems(hero,ItRw_FireArrow_01) > 0)
{
n = FireArrow_01;
RangedWeapon.munition = ItRw_FireArrow_01;
};
if (MagicArrow_01 > n) && (Npc_HasItems(hero,ItRw_MagicArrow_01) > 0)
{
n = MagicArrow_01;
RangedWeapon.munition = ItRw_MagicArrow_01;
};
//здесь переменная n не должна быть равна нулю!
};

if (Arrow_01 != 0) && (Npc_HasItems(hero, ItRw_Arrow_01) == 0)//если стрелы одеты, но их нет в инвентаре, значит они были выброшены
{
UnEquip_ItRw_Arrow_01();//ф-ция вызова снятия вида стрел
};
if (FireArrow_01 != 0) && (Npc_HasItems(hero, ItRw_FireArrow_01) == 0)
{
UnEquip_ItRw_FireArrow_01();
};
if (MagicArrow_01 != 0) && (Npc_HasItems(hero, ItRw_MagicArrow_01) == 0)
{
UnEquip_ItRw_MagicArrow_01();
};
};
};
//лук и арбалет - как примеры как должно быть, чтобы сработала вся система.

Создание таймера:
В Spacer'e создаем в любом месте вашего загружаемого уровня объект oCTriggerScript вот с такими свойствами:
Trigger.jpg

где fireDelaySec - это промежуток времени, через который будет выполняться функция SCRFUNC_TIMER.

Далее пишем в скриптах:
func void SCRFUNC_TIMER()
{
AppArrow();
Wld_SendTrigger("TIMER_01"); //Вызов триггера
};

В StartUp в загружаемом уровне нужно прописать 2 строчки:

func void Startup_[Имя уровня]()
{
ArrNum = 3; //кол-во видов стел
SCRFUNC_TIMER();
};


И конечно же прописать у ГГ данные лук и арбалет(лук и арбалет см. выше) и все 3 вида стрел.
Была убрана возможность стрелять этими видами стрел из арбалета, но если рассудить, то если бы ГГ попал в ситуацию, в которой у него не осталось бы болтов, а остались только стрелы и одет арбалет, то ситуация выглядела бы следующим образом(см. ниже), а если бы ГГ стал стрелять болтами из лука, то вероятнее всего он бы попал себе в руку:)
AppArrowInCrossBow.jpg
 

Lingviston

Участник форума
Регистрация
10 Май 2010
Сообщения
14
Благодарности
0
Баллы
150
У меня еще есть пару своих мыслец, попробую реализовать, пока что. А так с интересом послушал бы.
 

Ласковый Мороз

Участник форума
Регистрация
21 Апр 2010
Сообщения
91
Благодарности
3
Баллы
155
в GOthicSource при компелировании когда создаю нового непися на последнем етапе,вылезает startup.d(1173): Ошибка:Ожидаеться ';' пробывал ставить скобчки и всякое прочее не работает что делать?!
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
450
Благодарности
266
Баллы
230
Смотри внимательнее на синтаксис. Или лучше напиши сюда скрипт в каком месте у тебя возникает ошибка. Я имею ввиду не весь Startup, а ту процедуру, в которой у тебя возникает ошибка. Скорей всего ты забыл где-то сверху от ошибки поставить ";".
 
Сверху Снизу