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

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

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

MaGoth

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

Вложения

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

Диккен

Участник форума
Регистрация
12 Июн 2004
Сообщения
469
Благодарности
127
Баллы
210
Как называются строки и где они лежат.
Пример:
В Ребалансе 2.1 гарпии,големы,демоны-стреляют какими-то шариками.Ещё некоторые монстры могут исцелять се6я.
..\PrjGothic\AI\Monster\ZS_Monster\ZS_MM_Attack.d

if(self.aivar[AIV_MM_REAL_ID] == ID_HARPY)
{
if(Npc_GetDistToNpc(self,other) >= FIGHT_DIST_RANGED_INNER)
{
AI_TurnToNPC(self,other);
AI_PlayAni(self,"T_WARN");
AI_Wait(self,1);
Wld_PlayEffect("SPELLFX_ICELANCE",self,other,2,150,DAM_MAGIC,TRUE);
};
if(self.attribute[ATR_HITPOINTS] < 150)
{
AI_Wait(self,1);
Wld_PlayEffect("SPELLFX_HEAL",self,self,0,0,0,FALSE);
Npc_ChangeAttribute(self,ATR_HITPOINTS,100);


Объясните пож-ста, если нужно выполнить проверку условия (в диалоге):

if((Hlp_GetInstanceID(self) == Hlp_GetInstanceID(LordHagen)) || (Hlp_GetInstanceID(self) == Hlp_GetInstanceID(Parcival)))

1. То можно ли заменить этот блок на условие:

if(self.id == (LordHagen.id | Parcival.id))

2. почему GS выдает ошибку "нельзя пребразовать тип instance в int" , если условие в виде

if((Hlp_GetInstanceID(self) == (Hlp_GetInstanceID(LordHagen)) | Hlp_GetInstanceID(Parcival))

или

if((Hlp_GetInstanceID(self) == (LordHagen.id | Parcival.id))

но нет ошибки при

if((Hlp_GetInstanceID(self) == LordHagen.id)

2. Как присвоить глобальной переменной var C_Item значение, переданное в функцию через внутр. переменную?

var C_Item itmpick;
func int C_Beklauen(var C_Item itm,var int TheftGold)
itmpick =
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
444
Благодарности
264
Баллы
230
Диккен, ты не правильно понимаешь суть возвращаемого значения функции Hlp_GetInstanceID(), а также пытаешься работать с логическими операциями, не зная что они могут возвратить. Id объекта тоже тут ни при чём.

Прочитай про побитовые операции: И, ИЛИ, ОТРИЦАНИЕ, ВОЗВЕДЕНИЕ В СТЕПЕНЬ и т.д. Когда сам разберёшься - лучше будет.
Причём, когда собираешься с ними работать, просчитывай результат заранее, а не рассчитывай на авось.

Вот некоторые нюансы:
InstanceID - это идентификатор объекта. Т.е. порядковый номер, который присваивается при загрузке объекта в "мире".
self.id - это свойство объекта self класса C_NPC. В роли self может выступать кто угодно - тот, кого присвоят к глобальной переменной self.

2. Как присвоить глобальной переменной var C_Item значение, переданное в функцию через внутр. переменную?
Код:
var C_Item itmpick;
func int C_Beklauen(var C_Item itm,var int TheftGold)
{
	itmpick = itm;
};

Диккен, если любишь экспериментировать, то попробуй выполнить данный код в какой-нибудь функции одного из эликсиров маны, например:
Код:
instance ItPo_Mana_01(C_Item)
{
	name = NAME_Trank;
	mainflag = ITEM_KAT_POTIONS;
	flags = ITEM_MULTI;
	value = Value_ManaEssenz;
	visual = "ItPo_Mana_01.3ds";
	material = MAT_GLAS;
	on_state[0] = UseItPo_Mana_01;
	scemeName = "POTIONFAST";
	wear = WEAR_EFFECT;
	effect = "SPELLFX_MANAPOTION";
	description = "Эссенция маны";
	text[1] = NAME_Bonus_Mana;
	count[1] = Mana_Essenz;
	text[5] = NAME_Value;
	count[5] = Value_ManaEssenz;
};


func void UseItPo_Mana_01()
{
	Print(ConcatStrings("Id=",IntToString(LordHagen.id)));
	Print(ConcatStrings("InstanceId=",IntToString(Hlp_GetInstanceID(LordHagen))));
};
Вставляешь зелье через марвин или через скрипты.
Затем используешь. Так ты увидишь разницу между свойством и идентификатором.
 

Диккен

Участник форума
Регистрация
12 Июн 2004
Сообщения
469
Благодарности
127
Баллы
210
Прочитай про побитовые операции: И, ИЛИ, ОТРИЦАНИЕ, ВОЗВЕДЕНИЕ В СТЕПЕНЬ и т.д. Когда сам разберёшься - лучше будет.
Причём, когда собираешься с ними работать, просчитывай результат заранее, а не рассчитывай на авось.
Читал, смотрел на примеры в скриптах. Здесь тоже есть ошибка?
if(self.guild == (GIL_PAL | GIL_KDF | GIL_NOV))

self.id - это свойство объекта self класса C_NPC. В роли self может выступать кто
угодно - тот, кого присвоят к глобальной переменной self.
но ведь уточнил, что речь идет про диалог, т.е. self & other определены.
Если взять мой пример if(self.id == (LordHagen.id | Parcival.id)) , то эти числа должны совпадать или никогда не совпадут?

Не могу разобраться, не работает как нужно... помогите советом.
func int C_Beklauen(var int itemInstance,var int TheftGold)
SKIP
Я запутался в этих переменных((((

func int B_GiveInvItems(var C_Npc giver,var C_Npc taker,var int itemInstance,var int amount)
Код:
{
var string concatText;
var string itemname;
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))
{
[B]if(itemInstance == ItMi_Gold)[/B]

GS при проверке этого скрипта не выдает ошибок, но если я подобным образом вставляю в скрипт func int C_Beklauen(var C_Item itemInstance,var int TheftGold)
if(itemInstance == ItMi_Gold)
то "Ошибка. нельзя пребразовать тип inctance в int" ???
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
444
Благодарности
264
Баллы
230
Рассмотрим некоторое условие:
Код:
if(other.guild == (GIL_PAL | GIL_KDF))
Итак, сначала выполняется выражение в скобках, затем происходит операция сравнения "==" двух выражений.
Через поиск в скриптах находим:
Код:
const int GIL_PAL = 1;
const int GIL_KDF = 4;

"|" - операция логического сложения. Проще - операция "ИЛИ".
Переводим десятичные числа в двоичные, т.к. сложение делается в двоичной форме.
dec - десятичная форма записи, bin - двоичная.
dec = bin
1 = 001
4 = 100

Складываем столбиком и по принципу "Если хотя бы один из двух складываемых разрядов равен "1", то результат "истина", иначе - результат ложь".
Таблица истинности для этой операции:
1|1=1
1|0=1
0|1=1
0|0=0

В результате:
001
или
100
----
101

Число "101" двоичной системы счисления соответствует числу 5 в десятичной системе счисления.
const int GIL_NOV = 5;

Итого:
Код:
if(other.guild == GIL_NOV)
//если гильдия other равна GIL_NOV, то условие выполняется...

Диккен, если ты прочитал про побитовые операции, распиши-ка сам ответ на свой вопрос про условие:
Код:
if(self.guild == (GIL_PAL | GIL_KDF | GIL_NOV))

А вот правильно или нет - это решать тебе. Если ты уж взялся изучать чужие функции, то думай и анализируй информацию...
 

Диккен

Участник форума
Регистрация
12 Июн 2004
Сообщения
469
Благодарности
127
Баллы
210
GS при проверке этого скрипта не выдает ошибок, но если я подобным образом вставляю в скрипт func int C_Beklauen(var C_Item itemInstance,var int TheftGold)
if(itemInstance == ItMi_Gold)
то "Ошибка. нельзя пребразовать тип inctance в int" ???

Все, нашел решение в RedefinedFunc.dsc + int C_Beklauen(int#,int);

Диккен, если ты прочитал про побитовые операции, распиши-ка сам ответ на свой вопрос про условие:
Спасибо за ответ, я понял свою ошибку.
 

Диккен

Участник форума
Регистрация
12 Июн 2004
Сообщения
469
Благодарности
127
Баллы
210
func int C_IsTakenItemMyPossession(var C_Npc slf,var C_Npc oth,var C_Item itm)
Код:
func int C_IsTakenItemMyPossession(var C_Npc slf,var C_Npc oth,var C_Item itm)
{
 var int portalguild;
 portalguild = Wld_GetPlayerPortalGuild();
 if(Npc_OwnedByNpc(itm,slf))
 {
[B]if(Hlp_IsItem(itm,Holy_Hammer_MIS))[/B]
  {
   Hammer_Taken = TRUE;
  };
  return TRUE;
1. Возможно ли создавать подобные проверки условия без равенства == TRUE в новых функциях и не будет ли это ошибкой?

2. Будет ли это ошибкой, если создавать проверки вида:
var int pickitem;
func void B_Beklauen()
{
var int TheftDex;
var int CheckDex;
if(Hlp_IsItem(ItMi_Gold,PICKITEM)
3. В оригинале Г2а при воровстве предмета, которого нет в инвентаре персонажа, вызывается функция B_GiveInvItems(self,other,ITEM,1), например в DIA_Pal_201_Ingmar.d
В скриптах Возвращения перед вызовом B_GiveInvItems добавлена CreateInvItems(self,ITEM,1).
Возможно ли пропустить CreateInvItems и выполнять сразу B_GiveInvItems и не будет ли это ошибкой?

Не могу разобраться, не работает как нужно... помогите советом.
func int C_Beklauen(var int itemInstance,var int TheftGold)

PS. Разобрался в переменнных, теперь все работает)))

1. да, не будет
2. нет
3. да
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
444
Благодарности
264
Баллы
230
Диккен, приобрети справочник по скриптам. Он тебе поможет, если будешь стараться использовать его в разумных целях. Если нужен, пиши в личку.

Выписка из справочника:
int Hlp_IsItem (c_item item, int instanceName); - проверяет принадлежность предмета item к соответствующему типу instanceName, возвращает TRUE при соответствии, иначе – FALSE.


Есть некоторые допущения по поводу условий.

Допустимая запись:
Код:
if(Hlp_IsItem(itm,Holy_Hammer_MIS))[COLOR="DarkGreen"]//если предмет "itm" принадлежит инстанции "Holy_Hammer_MIS", то[/COLOR]
{
	[COLOR="DarkGreen"]//выполняем действие[/COLOR]
};

if(!Hlp_IsItem(itm,Holy_Hammer_MIS))[COLOR="DarkGreen"]//если предмет "itm" не принадлежит инстанции "Holy_Hammer_MIS", то[/COLOR]
{
	[COLOR="DarkGreen"]//выполняем действие[/COLOR]
};

Более понятная запись:
Код:
if(Hlp_IsItem(itm,Holy_Hammer_MIS) == TRUE)[COLOR="DarkGreen"]//если предмет "itm" принадлежит инстанции "Holy_Hammer_MIS", то[/COLOR]
{
	[COLOR="DarkGreen"]//выполняем действие[/COLOR]
};

if(Hlp_IsItem(itm,Holy_Hammer_MIS) == FALSE)[COLOR="DarkGreen"]//если предмет "itm" не принадлежит инстанции "Holy_Hammer_MIS", то[/COLOR]
{
	[COLOR="DarkGreen"]//выполняем действие[/COLOR]
};

"!" - знак отрицания.

AI_Constants.d:
Код:
const int TRUE = 1;
const int FALSE = 0;
 

Диккен

Участник форума
Регистрация
12 Июн 2004
Сообщения
469
Благодарности
127
Баллы
210
Диккен, если ты прочитал про побитовые операции, распиши-ка сам ответ на свой вопрос про условие:

Код:
if(self.guild == (GIL_PAL | GIL_KDF | GIL_NOV))

if(self.guild | GIL_PAL | GIL_KDF | GIL_NOV) == 5)
одно но, при GIL_NONE = 0 это тоже равно 5.

Таким образом можно например преобразовать условие
Код:
 if(Npc_HasItems(self,pickInstance) == 0)
   {
    return TRUE;
   };
к виду
Код:
 if(!Npc_HasItems(self,pickInstance))
   {
    return TRUE;
   };
выполнить return TRUE при 0
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
444
Благодарности
264
Баллы
230
if(self.guild | GIL_PAL | GIL_KDF | GIL_NOV) == 5)
одно но, при GIL_NONE = 0 это тоже равно 5.

Да, ты совсем в скобках запутался...
К тому же:
Код:
const int GIL_PAL = 1;
const int GIL_KDF = 4;
const int GIL_NOV = 5;

GIL_PAL | GIL_KDF | GIL_NOV = 1 + 4 + 5 = 10
А ты к этим 10 прибавляешь гильдию self. И что в итоге?
Ни одна из констант гильдий не принимает отрицательного значения. А у тебя получается сумма, да ещё и сравниваемая с числом "5". Подумай над этим.

А! Можно ещё прибавить гильдию Лорда Хагена. Затем всё поделить на
гильдию Ксардаса и умножить на здоровье ГГ. И, наконец преобразовать всё к типу int. Как тебе такое решение проблемы?
Я так и думал, что ты ничего не прочитал про побитовые операции.
Тренируй внимание и терпение!*flowers*
 

Диккен

Участник форума
Регистрация
12 Июн 2004
Сообщения
469
Благодарности
127
Баллы
210
GIL_PAL | GIL_KDF | GIL_NOV = 1 + 4 + 5 = 10
Нечего не понимаю... я складывал побитно в калькуляторе и почему операнд | вдруг превратился в + ?
if(self | GIL_PAL | GIL_KDF | GIL_NOV) == if(self or 1 or 4 or 5) == 5
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
444
Благодарности
264
Баллы
230
Диккен, молодец, разобрался!*flowers*
Я специально тебя запутал, чтобы ты старался разобраться сам.
Потому что когда не понимаешь чего-то, то оно тебя так и томит, пока не разберёшься сам.
Окей. Теперь ты понимаешь, что с побитовыми операциями нужно работать аккуратно?

Id Парсиваля = 252, Id Лорда Хагена = 200.
(252 | 200) = 252
Код:
if([COLOR="DarkOrange"][B]self[/B][/COLOR].id == (LordHagen.id | Parcival.id))[COLOR="DarkGreen"]//если id НПС self равно 252, то[/COLOR]
Зачем тогда Id Лорда Хагена?, когда можно записать так:
Код:
if([COLOR="DarkOrange"][B]self[/B][/COLOR].id == Parcival.id)[COLOR="DarkGreen"]//если id НПС self равно 252, то[/COLOR]


Рассмотрим другое условие:
Код:
[COLOR="DarkOrange"][B]if[/B][/COLOR]((Hlp_GetInstanceID([COLOR="DarkOrange"][B]self[/B][/COLOR]) == Hlp_GetInstanceID(LordHagen)) || (Hlp_GetInstanceID([COLOR="DarkOrange"][B]self[/B][/COLOR]) == Hlp_GetInstanceID(Parcival)))
[COLOR="DarkGreen"]//если идентификатор НПС self равен идентификатору Лорда Хагена или если идентификатор НПС self равен идентификатору Парсиваля, то...
//Другими словами: если НПС self - это Лорд Хаген или Парсиваль, то...[/COLOR]

Как видно, побитовые операции и логические операции сравнения имеют разный смысл.

Можно проверять и свойство НПС и идентификатор, но главное - это знать для чего это нужно делать...
Т.е. понимать смысл кода.
 

maggi1221

Участник форума
Регистрация
7 Окт 2010
Сообщения
218
Благодарности
4
Баллы
165
да забудь ты про битовые операции, они необходимы для работы с флагами...
установить/снять флаг, проверить флаг...
не зачем все усложнять, лучше просто написать условие с &&, ||, !

if(self.id == (LordHagen.id | Parcival.id)
наверное ты хотел написать так:
if ( ((self.id == LordHagen.id) || (self.id == Parcival.id)) )
 

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
Люди, а нахрена ВСЕ усложнять, когда можно сделать проще, и меньше шансов словить ЕГГОГ ?
 

GothMass


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

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
GothicXARDAS, Без проблем. Тутор Вама в руки, немного ковыряний в скриптах и все будет готово.
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
444
Благодарности
264
Баллы
230
GothicXARDAS, попробую тебе помочь, чем смогу...

Если посмотреть в Humans.mds, то можно найти там регистрацию мешей:
registerMesh ("HUM_BODY_NAKED0.ASC")
registerMesh ("HUM_BODY_BABE0.ASC")
registerMesh ("ARMOR_LEATHER_L.ASC")
registerMesh ("ARMOR_BDT_M.ASC")
registerMesh ("ARMOR_BDT_H.ASC")
registerMesh ("ARMOR_MIL_L.ASC")
registerMesh ("ARMOR_MIL_M.ASC")
registerMesh ("ARMOR_PAL_H.ASC")
registerMesh ("ARMOR_SLD_L.ASC")
registerMesh ("ARMOR_SLD_M.ASC")
registerMesh ("ARMOR_SLD_H.ASC")
registerMesh ("ARMOR_CORANGAR.ASC")
registerMesh ("ARMOR_DJG_L.ASC")
registerMesh ("ARMOR_DJG_M.ASC")
registerMesh ("ARMOR_DJG_H.ASC")
registerMesh ("ARMOR_DJG_CRAWLER.ASC")
registerMesh ("ARMOR_DJG_BABE.ASC")
registerMesh ("ARMOR_GOVERNOR.ASC")
registerMesh ("ARMOR_JUDGE.ASC")
registerMesh ("ARMOR_VLK_L.ASC")
registerMesh ("ARMOR_VLKBABE_L.ASC")
registerMesh ("ARMOR_SMITH.ASC")
registerMesh ("ARMOR_BAU_L.ASC")
registerMesh ("ARMOR_BAUBABE_L.ASC")
registerMesh ("ARMOR_NOV_L.ASC")
registerMesh ("ARMOR_KDF_L.ASC")
registerMesh ("ARMOR_KDF_H.ASC")
registerMesh ("ARMOR_XARDAS.ASC")
registerMesh ("ARMOR_DIEGO.ASC")
registerMesh ("ARMOR_LESTER.ASC")
registerMesh ("ARMOR_DEMENTOR.ASC")
registerMesh ("ARMOR_KDW_H.ASC")
registerMesh ("ARMOR_PRISONER.ASC")
registerMesh ("ARMOR_PAL_SKELETON.ASC")
registerMesh ("SKE_BODY.ASC")
registerMesh ("SKE_BODY2.ASC")
registerMesh ("SKE_FLY_BODY.ASC")
Как видно, тут броня и некоторые модели скелетов и людей.
Всё это можно применять к человеческой модели.Например, простейшее использование, без всяких дополнительных спец. эффектов:
Код:
instance ItPo_Mana_01(C_Item)
{
	name = NAME_Trank;
	mainflag = ITEM_KAT_POTIONS;
	flags = ITEM_MULTI;
	value = Value_ManaEssenz;
	visual = "ItPo_Mana_01.3ds";
	material = MAT_GLAS;
	on_state[0] = UseItPo_Mana_01;
	scemeName = "POTIONFAST";
	wear = WEAR_EFFECT;
	effect = "SPELLFX_MANAPOTION";
	description = "Эссенция маны";
	text[1] = NAME_Bonus_Mana;
	count[1] = Mana_Essenz;
	text[5] = NAME_Value;
	count[5] = Value_ManaEssenz;
};


func void UseItPo_Mana_01()
{
	Mdl_SetVisualBody([B][COLOR="DarkOrange"]self[/COLOR][/B],[COLOR="DarkRed"]"SKE_BODY"[/COLOR],DEFAULT,DEFAULT,[COLOR="DarkRed"]""[/COLOR],DEFAULT,DEFAULT,-1);[COLOR="DarkGreen"]//применяем визуализацию скелета для НПС self.[/COLOR]
};
Где:
self - НПС, использующий зелье маны,
"SKE_BODY" - название модели, которую хотим применить к НПС self,
DEFAULT - параметр по умолчанию,
"" - голова по умолчанию для этой модели,
"-1" - без брони.
 

Rendal

Участник форума
Регистрация
14 Дек 2010
Сообщения
240
Благодарности
2
Баллы
200
Помогите, что нужно прописать что бы при разговоре, НПС не вставал со скамьи, а разговаривал со мной оставаясь на скамье. Как например Диего в Г1.
 

GothMass


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

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
444
Благодарности
264
Баллы
230
GothicXARDAS, используй все те же самые функции, что и в случае присоеденения к любой из гильдий.
Хотя этот вопрос чисто для интереса, старайся больше пользоваться поиском, вспоминай похожие ситуации...
Код:
instance ItPo_Mana_01(C_Item)
{
	name = NAME_Trank;
	mainflag = ITEM_KAT_POTIONS;
	flags = ITEM_MULTI;
	value = Value_ManaEssenz;
	visual = "ItPo_Mana_01.3ds";
	material = MAT_GLAS;
	on_state[0] = UseItPo_Mana_01;
	scemeName = "POTIONFAST";
	wear = WEAR_EFFECT;
	effect = "SPELLFX_MANAPOTION";
	description = "Эссенция маны";
	text[1] = NAME_Bonus_Mana;
	count[1] = Mana_Essenz;
	text[5] = NAME_Value;
	count[5] = Value_ManaEssenz;
};


func void UseItPo_Mana_01()
{
	Npc_SetTrueGuild([B][COLOR="DarkOrange"]self[/COLOR][/B],GIL_KDF);[COLOR="DarkGreen"]//теперь self принадлежит к гильдии магов огня[/COLOR]
};
Таблица гильдий есть в справочнике.
 

GothMass


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