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

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!
  • Друзья, доброго времени суток!
    Стартовал новый литературный конкурс от "Ордена Хранителей" - "Пираты Миртанского моря".
    Каждый может принять в нём участие и снискать славу и уважение, а в случае занятия призового места ещё и получить награду. Дерзайте

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

MaGoth

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

Вложения

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

kraw


Модостроитель
Регистрация
11 Окт 2005
Сообщения
2.095
Благодарности
871
Баллы
295
Я бы советовал написать так:

Код:
if((((hero.guild == GIL_KDF) || (hero.guild == GIL_NOV)) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0)))
{
B_LogEntry(TOPIC_NgStPlFr_01_01,"Я нашел фрагмент таблички. Надо бы показать его Пирокару");

То есть (hero.guild == GIL_KDF) || (hero.guild == GIL_NOV) обернуть скобками

В остальном, вроде бы, нормально.
 

Хелдар

Участник форума
Регистрация
3 Июл 2012
Сообщения
2.450
Благодарности
780
Баллы
375
Ребята, делаю квест. По квесту необходимо, чтоб при появлении определенного предмета, в моем случае фрагмента плитки, начинался квест.

Дальнейшее общение по квесту, зависит от гильдии ГГ. Я сделал зацикленный триггер, прописал диалоги, но... я никак не могу сделать старт квеста. Ведь обычно квесты берутся через диалог, либо, как с хроманином, через прочтение документа.

Вот мой скрипт триггера, как я понимаю, старт должен идти через него.




Код:
func void EVT_TABLEFRAGMENT_01_FUNC()
{
if((hero.guild == GIL_KDF) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_01,"Я нашел фрагмент таблички. Надо бы показать его Пирокару");
}
else if((hero.guild == GIL_NOV) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_01,"Я нашел фрагмент таблички. Надо бы показать его Пирокару");
}
else if((hero.guild == GIL_MIL) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_02,"Я нашел фрагмент таблички. Надо бы показать его лорду Хагену");
}
else if((hero.guild == GIL_PAL) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_02,"Я нашел фрагмент таблички. Надо бы показать его лорду Хагену");
}
else if((hero.guild == GIL_SLD) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_03,"Я нашел фрагмент таблички. Надо бы показать его Ли");
}
else if((hero.guild == GIL_DJG) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_03,"Я нашел фрагмент таблички. Надо бы показать его Ли");
}
else if((hero.guild == GIL_KDW) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_04,"Я нашел фрагмент таблички. Надо бы показать его Ватрасу");
}
else if((hero.guild == GIL_NDW) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_04,"Я нашел фрагмент таблички. Надо бы показать его Ватрасу");
}
else if((hero.guild == GIL_KDM) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_05,"Я нашел фрагмент таблички. Надо бы показать его Ксардасу");
}
else if((hero.guild == GIL_NDM) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_05,"Я нашел фрагмент таблички. Надо бы показать его Ксардасу");
}
else if((hero.guild == GIL_GUR) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_06,"Я нашел фрагмент таблички. Надо бы показать его идолу Орану");
}
else if((hero.guild == GIL_SEK) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_06,"Я нашел фрагмент таблички. Надо бы показать его идолу Орану");
}
else if((hero.guild == GIL_TPL) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_07,"Я нашел фрагмент таблички. Надо бы показать его Гор На Кошу");
}
else
{
Wld_SendTrigger("NGSTPLFR_TRG_01");
};
};

И еще вопрос. Можно ли сократить выше приведенный скрипт, написав не

Код:
if((hero.guild == GIL_KDF) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_01,"Я нашел кусок таблички. Надо бы показать его Пирокару");
}
else if((hero.guild == GIL_NOV) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))
{
B_LogEntry(TOPIC_NgStPlFr_01_01,"Я нашел кусок таблички. Надо бы показать его Пирокару");
}

а

Код:
if(((hero.guild == GIL_KDF) || (hero.guild == GIL_NOV) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0)))
{
B_LogEntry(TOPIC_NgStPlFr_01_01,"Я нашел фрагмент таблички. Надо бы показать его Пирокару");

А где у тебя прописано
Код:
Log_CreateTopic(TOPIC_*имя квеста*,LOG_MISSION);
Log_SetTopicStatus(TOPIC_*имя квеста*,LOG_Running);
? Я что-то не заметил.
 

kraw


Модостроитель
Регистрация
11 Окт 2005
Сообщения
2.095
Благодарности
871
Баллы
295
Может это у него в предыдущих диалогах?
 

Test Level

Участник форума
Регистрация
1 Ноя 2011
Сообщения
1.770
Благодарности
557
Баллы
275
А где у тебя прописано
Код:
Log_CreateTopic(TOPIC_*имя квеста*,LOG_MISSION);
Log_SetTopicStatus(TOPIC_*имя квеста*,LOG_Running);
? Я что-то не заметил.


Я же спросил, где "прописывать?", а не показывал, где я прописал.

Я прописывал эти строки сразу перед
Код:
[/COLOR][I][COLOR=#141414][FONT=Consolas]Wld_SendTrigger("NGSTPLFR_TRG_01");[/FONT][/COLOR][/I][COLOR=#141414]

но толку ноль.
Прописывал их и после


Код:
if((hero.guild == GIL_KDF) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))[/FONT][/SIZE]
[FONT=Consolas]{[/FONT]
[FONT=Consolas]B_LogEntry(TOPIC_NgStPlFr_01_01,"Я нашел кусок таблички. Надо бы показать его Пирокару");


например, но эффекта опять же ноль.

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

Хелдар

Участник форума
Регистрация
3 Июл 2012
Сообщения
2.450
Благодарности
780
Баллы
375
Я же спросил, где "прописывать?", а не показывал, где я прописал.

Я прописывал эти строки сразу перед
Код:
[/COLOR][I][COLOR=#141414][FONT=Consolas]Wld_SendTrigger("NGSTPLFR_TRG_01");[/FONT][/COLOR][/I][COLOR=#141414]

но толку ноль.
Прописывал их и после


Код:
if((hero.guild == GIL_KDF) && (Npc_HasItems(hero,ItMi_Ng_Stone_Plate_Fragment_02) > 0))[/FONT][/SIZE][/FONT]
[FONT=Consolas][FONT=Consolas]{[/FONT][/FONT]
[FONT=Consolas][FONT=Consolas]B_LogEntry(TOPIC_NgStPlFr_01_01,"Я нашел кусок таблички. Надо бы показать его Пирокару");


например, но эффекта опять же ноль.

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

Вставлять это надо перед частными условиями, ведь квест создается при любом раскладе, только запись разная.
 

107-й

Участник форума
Регистрация
18 Дек 2011
Сообщения
59
Благодарности
3
Баллы
155
Подскажите, из всего что я привёл выше, где прописывается дальность фиксирования цели заклинанием?
Не вот это ли?
или вот это?
targetCollectRange = 1200;
Или за это отвечает какое-то не цифровое значение?
Подскажите, чтобы мне методом тыка не искать.
 

Dimus

★★★★★★★★★
Супермодератор
Регистрация
19 Июл 2010
Сообщения
5.574
Благодарности
4.169
Баллы
915
Прошу знатоков объяснить мне назначение странного фрагмента кода в функции B_SelectSpell():
func int B_SelectSpell(var C_Npc slf,var C_Npc oth)
{
var int dK_rnd;
var int dK_Mega;
if((slf.npcType == NPCTYPE_FRIEND) && Npc_IsPlayer(oth) && (oth.guild < GIL_SEPERATOR_HUM))
{
if((slf.guild == GIL_KDF) || (slf.aivar[AIV_MagicUser] == MAGIC_ALWAYS))
{
if(Npc_HasItems(slf,ItRu_Sleep) == 0)
{
CreateInvItems(slf,ItRu_Sleep,1);
};
B_ReadySpell(slf,SPL_Sleep,SPL_Cost_Sleep);
return TRUE;
}
else
{
return FALSE;
};
};
if((slf.guild == GIL_DMT) && (slf.aivar[AIV_MagicUser] == MAGIC_ALWAYS))
{
if(Npc_HasItems(slf,ItRu_InstantFireball) == 0)
{
CreateInvItems(slf,ItRu_InstantFireball,1);
};
if(Npc_HasItems(slf,ItRu_Deathbolt) == 0)
{
CreateInvItems(slf,ItRu_Deathbolt,1);
};
if(Npc_HasItems(slf,ItRu_Deathball) == 0)
{
CreateInvItems(slf,ItRu_Deathball,1);
};
if(Npc_HasItems(slf,ItRu_Firerain) == 0)
{
CreateInvItems(slf,ItRu_Firerain,1);
};
if(Npc_HasItems(slf,ItRu_Thunderstorm) == 0)
{
CreateInvItems(slf,ItRu_Thunderstorm,1);
};
if(Npc_HasItems(slf,ItRu_LightningFlash) == 0)
{
CreateInvItems(slf,ItRu_LightningFlash,1);
};
if(Npc_HasItems(slf,ItRu_Firestorm) == 0)
{
CreateInvItems(slf,ItRu_Firestorm,1);
};
if(Npc_HasItems(slf,ItRu_Skull) == 0)
{
CreateInvItems(slf,ItRu_Skull,1);
};
if(Hlp_GetInstanceID(slf) == Hlp_GetInstanceID(DMT_1299_OberDementor_DI))
{
B_ReadySpell(slf,SPL_Skull,SPL_Cost_Skull);
return TRUE;
}
else
{
if(Npc_IsDrawingWeapon(slf))
{
return TRUE;
};
if(slf.aivar[AIV_SelectSpell] <= 0)
{
dK_rnd = Hlp_Random(10);
slf.aivar[AIV_SelectSpell] += dK_rnd;
};
if(slf.aivar[AIV_SelectSpell] < 10)
{
if(Kapitel <= 3)
{
B_ReadySpell(slf,SPL_InstantFireball,SPL_COST_InstantFireball);
return TRUE;
}
else if(Kapitel <= 4)
{
B_ReadySpell(slf,SPL_Deathbolt,SPL_COST_Deathbolt);
return TRUE;
}
else
{
B_ReadySpell(slf,SPL_Deathball,SPL_COST_Deathball);
return TRUE;
};
}
else if(slf.aivar[AIV_SelectSpell] == 10)
{
slf.aivar[AIV_SelectSpell] = 11;
dK_Mega = Hlp_Random(100);
if(dK_Mega <= 2)
{
B_ReadySpell(slf,SPL_Firerain,SPL_Cost_Firerain);
return TRUE;
}
else if(dK_Mega <= 5)
{
B_ReadySpell(slf,SPL_Thunderstorm,SPL_Cost_Thunderstorm);
return TRUE;
}
else if(dK_Mega <= 10)
{
B_ReadySpell(slf,SPL_LightningFlash,SPL_Cost_LightningFlash);
return TRUE;
}
else
{
B_ReadySpell(slf,SPL_Firestorm,SPL_COST_Firestorm);
return TRUE;
};
}
else if(slf.aivar[AIV_SelectSpell] == 12)
{
slf.aivar[AIV_SelectSpell] = 0;
};
};
return TRUE;
};
if((slf.guild == GIL_KDF) || (slf.aivar[AIV_MagicUser] == MAGIC_ALWAYS))
{
if(Npc_HasItems(slf,ItRu_Concussionbolt) == 0)
{
CreateInvItems(slf,ItRu_Concussionbolt,1);
};
if(Npc_HasItems(slf,ItRu_InstantFireball) == 0)
{
CreateInvItems(slf,ItRu_InstantFireball,1);
};
if(Npc_HasItems(slf,ItRu_Deathball) == 0)
{
CreateInvItems(slf,ItRu_Deathball,1);
};
if(Npc_HasItems(slf,ItRu_FullHeal) == 0)
{
CreateInvItems(slf,ItRu_FullHeal,1);
};
if(self.attribute[ATR_HITPOINTS] < 100)
{
B_ReadySpell(slf,SPL_FullHeal,SPL_Cost_FullHeal);
return TRUE;
}
else if(C_NpcHasAttackReasonToKill(self))
{
if((self.flags == NPC_FLAG_IMMORTAL) || (Hlp_GetInstanceID(other) == Hlp_GetInstanceID(Raven)))
{
B_ReadySpell(slf,SPL_Deathball,SPL_COST_Deathball);
}
else
{
B_ReadySpell(slf,SPL_InstantFireball,SPL_COST_InstantFireball);
};
return TRUE;
}
else
{
B_ReadySpell(slf,SPL_ConcussionBolt,SPL_COST_Concussionbolt);
return TRUE;
};
};
if(slf.guild == GIL_PAL)
{
if(slf.fight_tactic == FAI_NAILED)
{
return FALSE;
};
if(Npc_HasItems(slf,ItRu_PalHolyBolt) == 0)
{
CreateInvItems(slf,ItRu_PalHolyBolt,1);
};
if((Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_MELEE) && C_NpcIsEvil(oth))
{
B_ReadySpell(slf,SPL_PalHolyBolt,SPL_Cost_PalHolyBolt);
return TRUE;
}
else
{
return FALSE;
};
};
if(slf.guild == GIL_SKELETON_MAGE)
{
if(Npc_HasItems(slf,ItRu_SumSkel) == 0)
{
CreateInvItems(slf,ItRu_SumSkel,1);
};
if(Npc_HasItems(slf,ItRu_IceCube) == 0)
{
CreateInvItems(slf,ItRu_IceCube,1);
};
if(Npc_HasItems(slf,ItRu_Icebolt) == 0)
{
CreateInvItems(slf,ItRu_Icebolt,1);
};
if(slf.aivar[AIV_SelectSpell] >= 6)
{
slf.aivar[AIV_SelectSpell] = 1;
};
if(!Npc_IsInState(oth,ZS_MagicFreeze) && (slf.aivar[AIV_SelectSpell] == 0))
{
B_ReadySpell(slf,SPL_IceCube,SPL_Cost_IceCube);
return TRUE;
}
else if((slf.aivar[AIV_SelectSpell] == 1) && (slf.lp < 5))
{
B_ReadySpell(slf,SPL_SummonSkeleton,SPL_Cost_SummonSkeleton);
return TRUE;
}
else
{
B_ReadySpell(slf,SPL_Icebolt,SPL_COST_Icebolt);
return TRUE;
};
};
if(slf.guild == GIL_ICEGOLEM)
{
if(Npc_HasItems(slf,ItRu_IceCube) == 0)
{
CreateInvItems(slf,ItRu_IceCube,1);
};
if((Npc_GetDistToNpc(slf,oth) < FIGHT_DIST_MELEE) || Npc_IsInState(oth,ZS_MagicFreeze))
{
return FALSE;
}
else
{
B_ReadySpell(slf,SPL_IceCube,SPL_Cost_IceCube);
return TRUE;
};
};
if(slf.guild == GIL_FIREGOLEM)
{
if(Npc_HasItems(slf,ItRu_InstantFireball) == 0)
{
CreateInvItems(slf,ItRu_InstantFireball,1);
};
if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_MELEE)
{
B_ReadySpell(slf,SPL_InstantFireball,SPL_COST_InstantFireball);
return TRUE;
}
else
{
return FALSE;
};
};
if(slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_SWAMP)
{
if(Npc_HasItems(slf,ItRu_InstantFireball) == 0)
{
CreateInvItems(slf,ItRu_InstantFireball,1);
};
if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_DRAGON_MAGIC)
{
B_ReadySpell(slf,SPL_InstantFireball,SPL_COST_InstantFireball);
return TRUE;
}
else
{
return FALSE;
};
};
if(slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_ROCK)
{
if(Npc_HasItems(slf,ItRu_InstantFireball) == 0)
{
CreateInvItems(slf,ItRu_InstantFireball,1);
};
if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_DRAGON_MAGIC)
{
B_ReadySpell(slf,SPL_InstantFireball,SPL_COST_InstantFireball);
return TRUE;
}
else
{
return FALSE;
};
};
if(slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_FIRE)
{
if(Npc_HasItems(slf,ItRu_InstantFireball) == 0)
{
CreateInvItems(slf,ItRu_InstantFireball,1);
};
if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_DRAGON_MAGIC)
{
B_ReadySpell(slf,SPL_InstantFireball,SPL_COST_InstantFireball);
return TRUE;
}
else
{
return FALSE;
};
};
if(slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_ICE)
{
if(Npc_HasItems(slf,ItRu_InstantFireball) == 0)
{
CreateInvItems(slf,ItRu_InstantFireball,1);
};
if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_DRAGON_MAGIC)
{
B_ReadySpell(slf,SPL_InstantFireball,SPL_COST_InstantFireball);
return TRUE;
}
else
{
return FALSE;
};
};
if(slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_UNDEAD)
{
Npc_ClearAIQueue(self);
if(Npc_HasItems(slf,ItRu_Deathball) == 0)
{
CreateInvItems(slf,ItRu_Deathball,1);
};
if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_DRAGON_MAGIC)
{
B_ReadySpell(slf,SPL_Deathball,SPL_COST_Deathball);
return TRUE;
}
else
{
return FALSE;
};
};
if(slf.aivar[AIV_MM_REAL_ID] == ID_ORCSHAMAN)
{
if(Npc_HasItems(slf,ItRu_InstantFireball) == 0)
{
CreateInvItems(slf,ItRu_InstantFireball,1);
};
if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_MELEE)
{
B_ReadySpell(slf,SPL_InstantFireball,SPL_COST_InstantFireball);
return TRUE;
}
else
{
return FALSE;
};
};
if(Hlp_GetInstanceID(slf) == Hlp_GetInstanceID(VLK_414_Hanna))
{
if(!Npc_IsInState(oth,ZS_MagicFreeze) && (Npc_HasItems(slf,ItSc_IceCube) > 0))
{
B_ReadySpell(slf,SPL_IceCube,SPL_Cost_Scroll);
return TRUE;
}
else if(Npc_HasItems(slf,ItSc_Firestorm) > 0)
{
B_ReadySpell(slf,SPL_Firestorm,SPL_Cost_Scroll);
return TRUE;
}
else
{
return FALSE;
};
};
return FALSE;
};
Почему в этом фрагменте используются идентификаторы self и other и нужно ли заменять их на slf и oth?:oops:
И можно ли объединить отдельные проверки на ID драконов в один фрагмент кода, т.е. так:
if((slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_SWAMP) || (slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_ROCK) || (slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_FIRE) || (slf.aivar[AIV_MM_REAL_ID] == ID_DRAGON_ICE))
{
if(Npc_HasItems(slf,ItRu_InstantFireball) == 0)
{
CreateInvItems(slf,ItRu_InstantFireball,1);
};
if(Npc_GetDistToNpc(slf,oth) > FIGHT_DIST_DRAGON_MAGIC)
{
B_ReadySpell(slf,SPL_InstantFireball,SPL_COST_InstantFireball);
return TRUE;
}
else
{
return FALSE;
};
};
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.816
Баллы
995
Dimus,
Почему в этом фрагменте используются идентификаторы self и other и нужно ли заменять их на slf и oth?
Наверное тот кто писал данный скрипт мало в них ориентировался, там и далее по тексту везде надо менять self и other на slf и oth.

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

Зы-зы, Драконов лучше не трогать, у них свои индивидуальные инстанции. Лучше оставить как есть... Хотя если предварительно тестировать в игре, то может и стоит, хз точно надо смотреть, ибо с ними возможны уникальные баги...
 

НастасьСанна

Участник форума
Регистрация
6 Дек 2012
Сообщения
350
Благодарности
521
Баллы
325
Почему в этом фрагменте используются идентификаторы self и other и нужно ли заменять их на slf и oth?
По логике, не только можно, но и нужно. Просто по факту здесь всегда slf == self и oth == other, поэтому работает без косяков. Мне еще где-то попадалась такая путаница между slf/self и oth/other.
И можно ли объединить отдельные проверки на ID драконов в один фрагмент кода
Можно, отчего ж нельзя. Рискну предположить, что предполагалась возможность разных заклинаний для разных драконов, поэтому в исходниках проверки и идут отдельно.
 

Dimus

★★★★★★★★★
Супермодератор
Регистрация
19 Июл 2010
Сообщения
5.574
Благодарности
4.169
Баллы
915
Ну хорошо, в этом фрагменте я заменил на slf и oth. Но при этом всё равно не особо понятен смысл кода:
если здоровье кастера меньше 100
{
приготовить полное исцеление
вернуть истину
}
иначе если кастер хочет убить цель
{
если кастер бессмертный или цель - Ворон
{
приготовить "шар смерти"
}
иначе
{
приготовить огненный шар
}
вернуть истину
}
иначе
{
приготовить стрелу сотрясения
вернуть истину
};
};
В игре бессмертны маги Огня Пирокар и Мильтен, а также все маги Воды. Но при чём тут условие для ИИ "цель - Ворон"? Ведь ГГ в одиночку проходит залы Аданоса и один сражается с бывшим рудным бароном.
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.816
Баллы
995
Dimus,
Но при этом всё равно не особо понятен смысл кода
А что там не понятного? Смотри на полную конструкцию ифа:

Код:
  // если агрессор Маг огня или агрессор всегда использует магию
  if(slf.guild == GIL_KDF) || (slf.aivar[AIV_MagicUser] == MAGIC_ALWAYS)
  {
      // создать в инвентаре агрессора следующие руны, если он их не имеет
      if(Npc_HasItems(slf,ItRu_Concussionbolt) == 0)
      {
          CreateInvItems(slf,ItRu_Concussionbolt,1);      // "Concussionbolt" (Название не переведено)
      };
      if(Npc_HasItems(slf,ItRu_InstantFireBall) == 0)
      {
          CreateInvItems(slf,ItRu_InstantFireBall,1);    // "Огненный шар"
      };
      if(Npc_HasItems(slf,ItRu_Deathball) == 0)
      {
          CreateInvItems(slf,ItRu_Deathball,1);          // "Deathball" (Название не переведено)
      };
      if(Npc_HasItems(slf,ItRu_FullHeal) == 0)
      {
          CreateInvItems(slf,ItRu_FullHeal,1);            // "Лечить сильное ранение"
      };
      // если текущая жизнь агрессора < 100 (Примечание: здесь и далее необходимо self заменить на slf)
      if(self.attribute[ATR_HITPOINTS] < 100)
      {
          // подготовить заклинание "Лечить сильное ранение"
          B_ReadySpell(slf,SPL_FullHeal,SPL_Cost_FullHeal);
          return TRUE;
      }
      // если причина атаки агрессора убийство цели
      else if(C_NpcHasAttackReasonToKill(self))
      {
          // если цель неуязвима или цель Равен (Примечание: Ошибка - необходимо self и other заменить на oth)
          if(self.flags == NPC_FLAG_IMMORTAL) || (Hlp_GetInstanceID(other) == Hlp_GetInstanceID(Raven))
          {
              // подготовить заклинание "Deathball"
              B_ReadySpell(slf,SPL_Deathball,SPL_Cost_Deathball);
          }
          else
          {
              // подготовить заклинание "Огненный шар"
              B_ReadySpell(slf,SPL_InstantFireball,SPL_Cost_InstantFireBall);
          };
          return TRUE;
      }
      else
      {
          // подготовить заклинание "Concussionbolt"
          B_ReadySpell(slf,SPL_Concussionbolt,SPL_Cost_Concussionbolt);
          return TRUE;
      };
  };
...

В игре бессмертны маги Огня Пирокар и Мильтен, а также все маги Воды. Но при чём тут условие для ИИ "цель - Ворон"? Ведь ГГ в одиночку проходит залы Аданоса и один сражается с бывшим рудным бароном.
А причем тут ГГ, если речь идет о любом маге огня, или том, кто использует магию?!
 

Dimus

★★★★★★★★★
Супермодератор
Регистрация
19 Июл 2010
Сообщения
5.574
Благодарности
4.169
Баллы
915
Спасибо, Иван, теперь стало понятно. Выходит, что проверка "цель - Ворон" - это незадействованная в игре заготовка на случай, если ГГ приведёт на рандеву с Вороном какого-нибудь мага.

Кстати, я перевёл названия заклинаний так: "Стрела смерти" (Deathbolt), "Шар смерти" (Deathball) и "Стрела сотрясения" (Concussionbolt).
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.816
Баллы
995
И да, в этом месте оба слова надо заменить на oth
Код:
// если цель неуязвима или цель Равен (Примечание: Ошибка - необходимо self и other заменить на oth)
          if(self.flags == NPC_FLAG_IMMORTAL) || (Hlp_GetInstanceID(other) == Hlp_GetInstanceID(Raven))

Кстати, я перевёл названия заклинаний так: "Стрела смерти" (Deathbolt), "Шар смерти" (Deathball) и "Стрела сотрясения" (Concussionbolt).
Не плохой вариант. :)
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.408
Благодарности
3.238
Баллы
525
Выходит, что проверка "цель - Ворон" - это незадействованная в игре заготовка

Теоретически, возможен вариант, когда ГГ начнёт драку с Вороном, но, убегая и уворачиваясь от ударов, выманит его аж к месту расположения магов Воды.

Предусмотрительные они (скриптеры Пираний), однако. :)
 

Dimus

★★★★★★★★★
Супермодератор
Регистрация
19 Июл 2010
Сообщения
5.574
Благодарности
4.169
Баллы
915
А как именно это можно сделать? Хотелось бы проверить твою догадку на сэйве перед разговором с Вороном.
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.408
Благодарности
3.238
Баллы
525
Точно такого сейва у меня нет. Возможно, подойдёт любой сейв на стадии после боя с Вороном, если вставить Ворона читами.

А трюк с выманиванием известен давно. В Г1 кое-кто выманивает болотожора на Стража, чтобы получить его двуручник в первой главе, В Г3 сам заманивал огров в Гельдерн, посмотреть на начинающуюся после этого суматоху. :)
 

Dimus

★★★★★★★★★
Супермодератор
Регистрация
19 Июл 2010
Сообщения
5.574
Благодарности
4.169
Баллы
915
Жаль, что у тебя нет такого сэйва. Я давно проходил храм Аданоса, но мне почему-то кажется, что дверь между залами с Радемесом и Вороном закрывается и её можно открыть только со стороны духа, и рудный барон не идёт вслед за ГГ в телепорт.
 

Kvincius

Участник форума
Регистрация
6 Ноя 2012
Сообщения
257
Благодарности
235
Баллы
210
Так как есть сейв, проверил - дверь в храме Аданоса действительно открывается только с одной стороны и Ворона оттуда никак не выманить.
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.816
Баллы
995
Теоретически, возможен вариант, когда ГГ начнёт драку с Вороном, но, убегая и уворачиваясь от ударов, выманит его аж к месту расположения магов Воды.
Скорее всего планировалось Мильтена сделать компаньоном или еще кого из круга Воды...
 
Сверху Снизу