Strona główna Lista użytkowników Fanpage OrtegaX YouTube Archi PeQs

Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
[G2 NK] - Ustawianie zaklęć NPC'om
Król

1,317 Postów
167 Tematów
Mężczyzna
Zarejestrowany: Feb 2016
Reputacja: 120

#1
Czy denerwowało Was kiedyś, że NPC korzystały praktycznie z dwóch zaklęć? Z kuli ognia i ogłuszającego pocisku. Wyjątkiem byli oczywiście poszukiwacze, których arsenał był nieznacznie powiększony. Załóżmy, że chcemy, aby magowie wody posługiwali się zaklęciami skupionymi wokół wody jak w przypadku Gothica 1.

Otwieramy plik B_SelectSpell.d znajdujący się w _Work\data\Scripts\Content\AI\Magic.

Napiszmy sobie kod dla magów wody. Wyszukujemy // ------ Magier ------ i kod wklejamy przed. Możemy opatrzyć go komentarzem np. // ------ Wasser-Magier ------. Ważne jest, aby wkleić ten kod PRZED blokiem oznaczonym jako // ------ Magier ------, ponieważ on definiuje zachowania dla Magów ognia ORAZ postaci z aivarem AIV_MagicUser ustawionym na MAGIC_ALWAYS. Właśnie taką wartość mają ustawioną magowie wody, więc jeśli nasz kod umieścimy poniżej, wówczas nie zobaczymy żadnych efektów w grze.
Kod:
if (slf.guild == GIL_KDW)
    {
        if (Npc_HasItems (slf, ItRu_IceCube) == 0) 
        {
            CreateInvItems (slf, ItRu_IceCube, 1);
        };
        
        if (Npc_HasItems (slf, ItRu_Geyser) == 0)
        {
            CreateInvItems (slf, ItRu_Geyser, 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 (!Npc_IsInState (oth, ZS_MagicFreeze))
        {
            B_ReadySpell (slf, SPL_ICECUBE, SPL_Cost_ICECUBE);
            return TRUE;
        }
        else
        {
            B_ReadySpell (slf, SPL_Geyser, SPL_Cost_Geyser);
            return TRUE;
        };
    };
Teraz po kolei - komentarz do danej części kodu umieściłem pod nim :)
Kod:
if (slf.guild == GIL_KDW)
Ten warunek odpowiada za to, aby z tego sposobu rzucania zaklęć korzystali tylko NPCy z gildią ustawioną na GIL_KDW co ustawiamy w pliku z postacią, np.
Kod:
    name     = "Saturas";
    guild         = GIL_KDW; 
    id         = 14000;
    voice     = 14;
    flags    = NPC_FLAG_IMMORTAL;                                                                    
    npctype        = NPCTYPE_MAIN;
    
    // ------ aivars ------
    aivar[AIV_MagicUser] = MAGIC_ALWAYS;
    aivar[AIV_IgnoresFakeGuild] = TRUE;
    aivar[AIV_IgnoresArmor]     = TRUE;
Teraz dochodzimy do części odpowiadającej za dodawanie NPCom interesujących ich run.
Kod:
if (Npc_HasItems (slf, ItRu_IceCube) == 0) 
        {
            CreateInvItems (slf, ItRu_IceCube, 1);
        };
        
        if (Npc_HasItems (slf, ItRu_Geyser) == 0)
        {
            CreateInvItems (slf, ItRu_Geyser, 1);
        };
        
        if (Npc_HasItems (slf, ItRu_FullHeal) == 0)
        {
            CreateInvItems (slf, ItRu_FullHeal, 1);
        };
Mówiąc najprościej, mamy trzy, niezależne warunki. Jeśli NPC nie posiada runy bryły lodu, otrzyma jedną. Jeśli nie ma runy gejzeru, otrzyma jedną. Jeśli nie ma runy pełnego leczenia, otrzyma jedną.
----
Teraz najbardziej interesująca nas część, czyli konkretne zachowanie NPCów. Działanie tej części kodu również jest proste. 
Kod:
        if (self.attribute[ATR_HITPOINTS] < 100) 
        {
            B_ReadySpell (slf, SPL_FullHeal, SPL_Cost_FullHeal);
            return TRUE;
        }
Na początku gra sprawdza czy NPC ma mniej niż 100 hp. Jeśli ma mniej, wówczas wyciągnie runę pełnego leczenia. 
Kod:
       else if (!Npc_IsInState (oth, ZS_MagicFreeze))
        {
            B_ReadySpell (slf, SPL_ICECUBE, SPL_Cost_ICECUBE);
            return TRUE;
        }
W przeciwnym wypadku jeśli cel nie jest zamrożony, NPC wykorzysta runę bryły lodu.
Kod:
      else
        {
            B_ReadySpell (slf, SPL_Geyser, SPL_Cost_Geyser);
            return TRUE;
        };
W przeciwnym wypadku będzie korzystać z zaklęcia gejzeru. 
Warunki są cały czas sprawdzane od góry, więc miejsce umieszczenia danych bloków warunkowych ma znaczenie. 
Aha i jeszcze jedna rzecz. 
return TRUE oznacza, że NPC zostaje w trybie rzucania zaklęć. Jeśli natomiast damy return FALSE, NPC przejdzie do trybu walki wręcz/zasięgowej. Tutaj możemy natrafić na błędy, np. NPC wyciągnie broń i nagle stanie w bezruchu. Najprawdopodobniej przy kolejnym obrocie pętli znowu natrafiamy na return TRUE, ale ponieważ NPC jest w trybie walki wręcz/zasięgowej, wówczas nie jest w stanie rzucać zaklęć i się blokuje.

Twórca: Kruk

Odpowiedz
Podziękowanie dał/dali: Gepsiu




Użytkownicy przeglądający ten wątek: 1 gości
Styl forum:
Witaj!
or Rejestracja?