[G1] Wyjaśnienie dialogu strażnika, który nie przepuszcza gracza. 6070 12

O temacie

Autor Draquer

Zaczęty 21.04.2019 roku

Wyświetleń 6070

Odpowiedzi 12

Draquer

Draquer

Użytkownicy
Problematyk :F
posty360
Propsy23
ProfesjaNierób
  • Użytkownicy
  • Problematyk :F
Potrzebuję żeby ktoś wytłumaczył mi co się dzieje w takich warunkach jak np. tutaj:
Spoiler
FUNC INT Info_Grd_212_FirstWarn_Condition()
{
   if ((hero.aivar[AIV_GUARDPASSAGE_STATUS]== AIV_GPS_BEGIN)
   &&  (self.aivar[AIV_PASSGATE]         == FALSE      )
   &&   (Npc_GetAttitude(self,hero)         != ATT_FRIENDLY   )
   &&   (Hlp_StrCmp(Npc_GetNearestWP(self), self.wp)      ))
   {
      return TRUE;
   };
};

albo tutaj:

Spoiler
   &&  (Npc_GetDistToWP(hero,Grd_212_CHECKPOINT)   < (hero.aivar[AIV_LASTDISTTOWP]-100))
   &&   (Hlp_StrCmp(Npc_GetNearestWP(self),self.wp)                              ))

Czym jest "aivar"? Nie znalazłem ich nazw w Story_Globals.d, więc zakładam że to nie zmienne?
Czy można zrobić dialog na zwykłych zmiennych, czy trzeba robić to tak jak Piranie w powyższych przykładach?
W czym "aivar" jest lepszy od zwykłych zmiennych?
 
Spoiler
#include<iostream>
using namespace std;

int main()
{
      cout << "Hello theModders" <<endl;
      return 0;
}

outlander

outlander

Użytkownicy
posty471
Propsy237
ProfesjaReżyser
  • Użytkownicy
Aivar to jest zmienna, która jest przypisana do NPC. Ich ilość jest chyba limitowana i nie można dodać nowych. Można jedynie przerobić/wykorzystać stare jeśli dobrze pamiętam.
Przykładowe wykorzystanie:
Masz aivara np AIV_NPCjestChory. Przypisujesz wartość 1 dla wszystkich chorych strażników w starym obozie. I potem w skrypcie powitań dajesz np coś takiego:
if (self.aivar[AIV_NPCjestChory]         == FALSE      )
{
//normalne "Za Gomeza!"
}
else
{
//jakieś inne powiedzenie np "A psik... Za Gomeza!"
};
W tym kodzie co podałeś to po prostu jest sprawdzany aivar czy ten strażnik może przepuścić gracza. Drugi warunek dotyczy odległości między NPC tak w uproszczeniu.
 

Draquer

Draquer

Użytkownicy
Problematyk :F
posty360
Propsy23
ProfesjaNierób
  • Użytkownicy
  • Problematyk :F
Ok, dzięki za objaśnienie, a co oznacza "Print Globals (PD_MISSION)"?

EDIT: Jak ustawić zwrot NPC? Dodałem NPC strażnika i stoi plecami do wejścia.
 
Spoiler
#include<iostream>
using namespace std;

int main()
{
      cout << "Hello theModders" <<endl;
      return 0;
}

Patrix9999

Patrix9999

Użytkownicy
posty127
Propsy38
Profesjabrak
  • Użytkownicy
Odnośnie tych AIVAR, zwrócę tylko uwagę, że AIVAR to tablica zmiennych typu integer (liczba całkowita) o stałym rozmiarze, czyli 100, którą posiada każdy npc.

Pytanie numer 1:
Kod funkcji PrintGlobals jest częściowo zrealizowany w daedalusie.
Głównie funkcja służy do ułatwienia testowania (debugowania) nazw instancji self, other, hero, victim, item w odpowiednich sytuacjach. Funkcja ta printuje odpowiednie informacje do ZSpy odnośnie tych dynamicznie zmienianych instancji do silnika, niestety, nie można jej wykorzystać (o ile się dobrze orientuje) tak po prostu. Problem polega na tym, że silnik gry posiada następuje rzeczy w swoim systemie do printowania takich komunikatów pomocniczych:
-Włączony tryb debugowania (showDebug)
-debugChannel (musi być włączony by w ogóle dane wiadomości z danego kanału się pokazały)
-Dana instancja musi być debugowana

Pokaże jak przykładowo wygląda output takiej funkcji, po małej zabawie Reverse Engineeringiem:
https://i.imgur.com/dThT5Pf.png

w ZSpy dodatkowo możemy takie logi zapisać do pliku tekstowego, nie mniej jednak, pomimo tego że nie można tego użyć (a jeśli można, to nie jest to takie proste), o ile chcesz mieć takie printy pomocnicze w zSpy, możesz skorzystać z tych funkcji (o ile posiadasz Ikarusa):
-MEM_Debug
-MEM_Warn
-MEM_Error
-MEM_Info

Pytanie nr 2:
Z tego co się orientuje, wystarczy w spacerze ustawić waypoint/freepoint pod odpowiednim kątem.
 

Fabio

Fabio

The Modders
posty3477
Propsy2157
ProfesjaSkrypter
  • The Modders
@Draquer freepoint określa kierunek, w którym zwrócony jest potwór lub NPC, waypoint niekoniecznie. Czasem też musisz użyć waypointa i freepointa jednocześnie, na przykład jeśli chcesz, żeby postacie ze sobą rozmawiały (standardowe smalltalki), o tym jednak przeczytasz gdzie indziej.

Draquer

Draquer

Użytkownicy
Problematyk :F
posty360
Propsy23
ProfesjaNierób
  • Użytkownicy
  • Problematyk :F
A skoro już o tym mowa to zapytam:
Moja znajomość C++ jest na poziomie znajomości typów danych (int, float, bool itd), warunku if, switch ... case, pętli do ... while, funkcji (podstawy podstaw, argumenty średnio kumam) i tablic jednowymiarowych, czy to wystarczy do zapoznania się z Ikarusem i LeGo czy lepiej żebym jeszcze lepiej zapoznał się z C++ i dopiero potem brał się za takie rzeczy?

A co do waypointu, to ustawiłem swojego NPC na waypoincie starego NPC, który stał poprawnie, popatrzę jeszcze w Spacerze, w każdym razie dzięki za zainteresowanie tematem. :D

EDIT: Dzięki @Fabio, problem rozwiązany

EDIT2: Jak zmienić wartość "self.aivar[AIV_PASSGATE]" na TRUE?
           W skrypcie Thorusa, zmienia się ta wartość dla strażnika o ID 212 w taki sposób:          wache212.aivar[AIV_PASSGATE] = TRUE;
Jednak mój strażnik ma ID 6002 i nie pomógł zapis "wache6002.aivar[AIV_PASSGATE] = TRUE;"
 
Spoiler
#include<iostream>
using namespace std;

int main()
{
      cout << "Hello theModders" <<endl;
      return 0;
}

Fabio

Fabio

The Modders
posty3477
Propsy2157
ProfesjaSkrypter
  • The Modders
@Draquer nie, w żadnym wypadku, o ile nie chcesz tworzyć bardziej wymagających rzeczy jak np. własnych bibliotek w C++ (AST chociażby). Co do Ikarusa/LeGo to nie wiem, ale nie brałbym się za to na twoim miejscu póki nie ogarniasz jeszcze podstaw moddingu Gothica.

Patrix9999

Patrix9999

Użytkownicy
posty127
Propsy38
Profesjabrak
  • Użytkownicy
W zasadzie, to takowa wiedza wystarczy na spokojnie by używać Ikarusa/LeGo, z czasem jednak jeśli będziesz chciał wiedzieć jak coś dokładnie działa, albo napisać coś samemu, będziesz musiał się pouczyć np: bardziej o RE, ASM, itp, wszystko zależy od tego co chcesz zrobić, ale nie ma co się bać Ikarus'a/LeGo, implementują one bardzo dużo rzeczy z których może korzystać każdy bez żadnej "specjalistycznej" wiedzy ;).

Co do twojego drugiego pytania:

Zajrzyj do pliku Story/Npc_Globals.d
Tam znajdziesz odpowiedź na swoje pytanie.
 

Draquer

Draquer

Użytkownicy
Problematyk :F
posty360
Propsy23
ProfesjaNierób
  • Użytkownicy
  • Problematyk :F
W G1 jest jedynie Story_Globals.d, nie ma tam aivarów, ale postanowiłem dodać taką zmienna "var int wache6002.aivar [AIV_PASSGATE]", taką samą wpisałem w dialogu strażnika i niestety kompilator wyrzuca błąd "Unknow indentifier: AIVAR"
 
Spoiler
#include<iostream>
using namespace std;

int main()
{
      cout << "Hello theModders" <<endl;
      return 0;
}

Patrix9999

Patrix9999

Użytkownicy
posty127
Propsy38
Profesjabrak
  • Użytkownicy
Nie wiem jak to wygląda w G1, raczej prawie tak samo jak w G2.
Najpierw tworzysz zmienną npc'a w taki sposób:

var C_Npc nazwaZmiennej;
a potem w funkcji przypisujesz do niej Npc'a w taki sposób:

nazwaZmiennej = Hlp_GetNpc(Instancja_Npc);

@Edit:
Z tego co widzę, w G1 są tworzone zmienne lokalne (w obrębie funkcji).
W G2 masz plik ze zmiennymi globalnymi, a później RAZ przypisujesz coś do nich.
Niewiele to zmienia, dalej to co napisałem, ma sens.
 

Draquer

Draquer

Użytkownicy
Problematyk :F
posty360
Propsy23
ProfesjaNierób
  • Użytkownicy
  • Problematyk :F
Mam wrażenie że w G1 również są zmienne globalne, a przynajmniej tak mi się wydaje z powodu nazwy pliku Story_Globals.d
A więc dodałem takie dwie linijki w Story_Globals.d
Spoiler
var C_NPC wache6002.aivar[AIV_PASSGATE];
wache6002.aivar[AIV_PASSGATE] = Hlp_GetNpc(HNT_6002_Guard);
i z powodu 2 linijki pojawia się błąd
Spoiler
U:PAR: Syntax error: WACHE6002.AIVAR
 
Spoiler
#include<iostream>
using namespace std;

int main()
{
      cout << "Hello theModders" <<endl;
      return 0;
}

Patrix9999

Patrix9999

Użytkownicy
posty127
Propsy38
Profesjabrak
  • Użytkownicy
Źle to robisz, najpierw musisz pobrać Npc'a za pomocą funkcji Hlp_GetNpc, potem możesz zmodyfikować aivar jego.

var C_Npc wache6002;
wache6002 = Hlp_GetNpc(HNT_6002_Guard);

wache6002.aivar[AIV_PASSGATE] = 1;

@Edit ten cały kod musisz umieścić w jakiejś funkcji (np: która wykonuje się w jakimś konkretnym dialogu) ;P.
 

Draquer

Draquer

Użytkownicy
Problematyk :F
posty360
Propsy23
ProfesjaNierób
  • Użytkownicy
  • Problematyk :F
Ok, to by się zgadzało z tym co pisałeś o zmiennych lokalnych.
Wszystko działa, temat można zamknąć.
 
Spoiler
#include<iostream>
using namespace std;

int main()
{
      cout << "Hello theModders" <<endl;
      return 0;
}


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry