2Finsternis:
Не мог бы ты поделиться своим опытом в плане "Невидимых мясных жуков" Очень мне понравилась такая фишка.
|
Очень просто ;) Создаем зверушку - бессмертного мясного жука-призрака размером 0.01 от обычного. Заметить его невозможно, можно только услышать его шуршание вблизи места, где он сидит :)
[pre]
prototype Mst_Default_HelperBug(C_Npc) {
name[0] = "";
guild = GIL_MEATBUG;
flags = NPC_FLAG_IMMORTAL | NPC_FLAG_GHOST;
level = 1;
noFocus = 1;
bodyStateInterruptableOverride = 1;
attribute[ATR_STRENGTH] = 1;
attribute[ATR_DEXTERITY] = 1;
attribute[ATR_HITPOINTS_MAX] = 10;
attribute[ATR_HITPOINTS] = 10;
attribute[ATR_MANA_MAX] = 0;
attribute[ATR_MANA] = 0;
protection[PROT_BLUNT] = 0;
protection[PROT_EDGE] = 0;
protection[PROT_POINT] = 0;
protection[PROT_FIRE] = 0;
protection[PROT_FLY] = 0;
protection[PROT_MAGIC] = 0;
damagetype = DAM_EDGE;
senses = SENSE_SMELL;
senses_range = 0;
aivar[AIV_MM_FollowInWater] = FALSE;
start_aistate = ZS_MM_AllScheduler;
aivar[AIV_MM_WuselStart] = OnlyRoutine;
damage [DAM_INDEX_EDGE] = 0;
};
func void B_SetVisuals_HelperBug() {
Mdl_SetVisual (self, "Meatbug.mds");
Mdl_SetVisualBody (self, "Mbg_Body", DEFAULT, DEFAULT, "", DEFAULT, DEFAULT, -1);
Mdl_SetModelScale (self, 0.01, 0.01, 0.01);
};
instance HelperBugBaumsaege(Mst_Default_HelperBug) {
B_SetVisuals_HelperBug ();
aivar[AIV_MM_REAL_ID] = ID_MEATBUG_BAUMSAEGE;
};
[/pre]
В ZS_MM_AllScheduler прописываем в самом начале:
[pre]
if ((self.guild == GIL_MEATBUG))
{
if (self.aivar[AIV_MM_REAL_ID] == ID_MEATBUG_BAUMSAEGE)
{
AI_StartState (self, ZS_MM_Rtn_Baumsaege, 1, "");
return;
}
[/pre]
Создаем ZS_MM_Rtn_Baumsaege.d и в нем пишем эту самую операцию:
[pre]
func void ZS_MM_Rtn_Baumsaege()
{
Perception_Set_Helper_Rtn ();
B_MM_DeSynchronize ();
if (Hlp_StrCmp (Npc_GetNearestWP (self), self.wp) == FALSE)
{
AI_GotoWP (self, self.wp);
};
};
var int SayOneTimeBaumsaege;
func int ZS_MM_Rtn_Baumsaege_Loop()
{
if (Npc_GetStateTime(self) >= 5)
{
Npc_SetStateTime (self, 0);
if (Npc_GetBodyState (hero) == BS_MOBINTERACT_INTERRUPT)
{
var string DetMob;
DetMob = Npc_GetDetectedMob(hero);
if (Hlp_StrCmp (DetMob, "BAUMSAEGE"))
{
if (KnowHowToMakeArrows == TRUE)
{
B_GiveInvItems(self, hero, ItRw_Arrow, 1);
}
else
if (SayOneTimeBaumsaege == FALSE)
{
AI_PrintScreen ("Интересно - а что бы я мог так напилить?",
-1, YPOS_ItemGiven, FONT_ScreenSmall, 2);
SayOneTimeBaumsaege = TRUE;
};
};
};
};
return LOOP_CONTINUE;
};
func void ZS_MM_Rtn_Baumsaege_End()
{
};
[/pre]
Т.е. баг сидит и проверяет - если ГГ делает что-то стоя у бревна - значит пришла пора подкладывать ему в инвентарь стрелы.
Perception_Set_Helper_Rtn () здесь на всякий случай отрубает багу "органы чувств". Т.е.
[pre]
Npc_PercDisable (self, PERC_ASSESSMAGIC);
Npc_PercDisable (self, PERC_ASSESSDAMAGE);
и.т.п.
[/pre]
Осталось только вставить наших багов рядом с бревнами:
[pre]
Wld_InsertNpc (HelperBugBaumsaege, "NW_CITY_MERCHANT_SHOP01_FRONT_01");
Wld_InsertNpc (HelperBugBaumsaege, "NW_CITY_POOR_SAW");
Wld_InsertNpc (HelperBugBaumsaege, "NW_TAVERNE_03");
Wld_InsertNpc (HelperBugBaumsaege, "NW_CITY_HABOUR_08");
Wld_InsertNpc (HelperBugBaumsaege, "NW_CASTLEMINE_TROLL_04_C");
Wld_InsertNpc (HelperBugBaumsaege, "NW_CASTLEMINE_TOWER__MOBSI");
Wld_InsertNpc (HelperBugBaumsaege, "NW_BIGFARM_KITCHEN_OUT_01");
Wld_InsertNpc (HelperBugBaumsaege, "NW_FARM3_STABLE_OUT_01");
Wld_InsertNpc (HelperBugBaumsaege, "NW_FARM4_TILL");
[/pre]
Теперь при первой попытке попилить любое бревно в Хоринисе вылезет фраза "И чтобы я мог так напилить"?
После разговора с тем, кто учить пилить стрелы ставим KnowHowToMakeArrows в TRUE и теперь можно просто оставить ГГ пилить у ближайшего бревна, а самому пойти в магазин за пивом ;) Скорость невелика - за время похода он напилит 300-400 стрел.
И еще - если жук больше не нужен, можно его самоубить ;) Но делать это надо только в _End() функции. Если убить бага в _Loop(), то игра трапнется. Т.е., например:
[pre]
func int ZS_MM_Rtn_DropItem_Loop()
{
if (Npc_GetStateTime(self) >= 2)
{
Npc_SetStateTime (self, 0);
if (HeroHasAnItem)
{
if (Npc_HasItems (hero, ItKe_OC_Store) == 0)
{
var c_npc own;
// кому пренадлежит комната, в которой ГГ?
own = Npc_GetPortalOwner(hero);
HeroHasAnItem = FALSE;
if (Hlp_IsValidNpc(own))
{
if (Hlp_GetInstanceID (own) == Hlp_GetInstanceID (Engor))
{
B_GivePlayerXP(XP_Ambient * 2);
if ((MIS_CassiaGoldCup == LOG_Running) ||
(MIS_CassiaGoldCup == LOG_Success))
{
B_LogEntry (Topic_CassiaGoldCup,
"Я подбросил ключ в комнату Энгора.");
};
// баг сделал дело, прекращаем цикл
return LOOP_END;
};
};
};
} else if (Npc_HasItems (hero, ItKe_OC_Store) >= 1)
{
HeroHasAnItem = TRUE;
};
};
return LOOP_CONTINUE;
};
func void ZS_MM_Rtn_DropItem_End()
{
self.flags = NPC_FLAG_GHOST; // сбросим флаг бессмертия
Npc_ChangeAttribute (self, ATR_HITPOINTS, -self.attribute[ATR_HITPOINTS_MAX]);
};
[/pre]