Показать сообщение отдельно
Старый 15.08.2005, 10:09   #737
dixie

AGFC
Гость
 
Сообщений: n/a

По умолчанию Re: Скриптинг в Готике

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]
Ответить с цитированием