Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

System Dialogów v2

Ostatnio zmodyfikowano 2024-06-14 04:56
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
System Dialogów v2
» 2024-06-06 21:04:43
Witam. Spać nie mogłem za sprawą pekfosa i korci mnie strasznie ten styl dialogów. Tylko nie wiem od czego zacząć. Rozpisałem sobie przykładowy dialog, ale nie wiem jak go podzielić na funkcje i jakich struktur użyć.


-"W czym mogę pomóc?" (NPC)
 -"Kim jesteś?" (Player)
  -"Nazywam się Gorn i jestem myśliwym." (NPC)
 -"Na co polujesz?" (Player)
  -"Poluję na dziobaki oraz wilczury" (NPC)
 -"Jak idą łowy?" (Player)
  -"Nie najlepiej. Ostatnio coraz mniej zwierzyny. Jak tak dalej pójdzie, to będę musiał zmienić tereny łowieckie." (NPC)
   -"W okolicy nadal widać potwory." (Player)
    -"Tak, ale jest ich coraz mniej. Kiedyś to było, a teraz zwyczajnie mało." (NPC)
   -"Masz rację. Nie ma już tu na co polować." (Player)
 -<ifHasItem "wolf skin" 1> "Mam skórę wilczura. Chcesz ją ode mnie odkupić?" (Player)
  -"Chętnie. Dam ci za każdą miksturę leczniczą" (NPC)
   -"Proszę oto skóra wilczura" <removeItem "wolf skin" 1> (Player)
    -"Masz, w zamian mikstura lecznicza. Tak jak się umawialiśmy." <addItem "potion" 1> (NPC)
   -"Może innym razem ..." (Player)
 -<ifHasItem "dziobak skin" 1> "Mam skórę dziobaka. Chcesz ją odkupić?" (Player)
  -"Za skórę dziobaka, mogę dać Ci 10 sztuk złota." (NPC)
   -"Zgoda. Oto Twoja skóra." <removeItem "dziobak skin" 1> (Player)
    -"Trzymaj to złoto." <addItem "gold" 10> (NPC)
   ="Może innym razem ..." (Player)
 -"Żegnaj" <end>

ogólnie dialog ma strukturę następującą (z tym dam radę)
<warunek> "Tekst Dialogu" <funkcja> (Player)
 lub
"Tekst Dialogu" <funkcja> (NPC)

struktury zapewne powinny wyglądać tak
C/C++
class DialogueOption {
public:
   
std::wstring text;
   
int nextDialogueID;
   
std::function < bool() > conditions;
   
std::function < void() > actions;
   
   
};

class Dialogue {
public:
   
int id;
   
std::wstring text;
   
std::vector < DialogueOption > options;
   
std::function < void() > actions;
};

nie mam pojęcia jak wczytać ten dialog ..
P-181224
pekfos
» 2024-06-06 23:09:39
Do czego jest (Player) i (NPC)? Jak tylko dla czytelności, by było widać czy to jest opcja czy odpowiedź, to krócej byłoby to załatwić tym pierwszym znakiem w linii (który zresztą pominąłeś w opisie). Znak - mógłby być wymagany dla opcji i nie byłoby go dla odpowiedzi. Trochę by to uprościło i ograniczyło ilość pisania. Na dobrą sprawę można nawet darować sobie wcięcie między odpowiedzią i opcjami, skoro są rozróżnione znakiem -:
"W czym mogę pomóc?"
-"Kim jesteś?"
    "Nazywam się Gorn i jestem myśliwym."
-"Na co polujesz?"
Więc dwa rodzaje linii by miały taką gramatykę:
- <warunek>? "Tekst Dialogu" <funkcja>?
"Tekst Dialogu" <funkcja>?
Znak zapytania określa opcjonalny element. Pewnie należałoby dopuszczać spacje/tabulacje między każdym elementem by parser nie był wybredny.

Co do ładowania takiej zagnieżdżonej struktury, po prostu ładuj linie po kolei i patrz na ilość tabulacji na początku linii. Można to zrobić funkcją rekurencyjną, chociaż pewnie prościej utrzymywać tu własny stos. Przykład:
C/C++
#include <iostream>
#include <string>
#include <vector>

bool parse()
{
   
std::string line, dialogue;
   
std::vector < std::string > stack;
   
   
while( std::getline( std::cin, line ) )
   
{
       
size_t tabs = line.find_first_not_of( "\t" );
       
if( tabs == std::string::npos )
           
 continue; // pusta linia - ignoruj
       
        // Aktualna linia jest mniej wcięta niż poprzednia. Przywróć stan do dialogu na poziomie wynikającym z wcięcia
       
while( tabs < stack.size() )
       
{
           
dialogue = stack.back();
           
stack.pop_back();
       
}
       
       
if( line[ tabs ] == '-' )
       
{
           
if( tabs != stack.size() || dialogue.empty() )
               
 return false; // Opcja nie może być inaczej wcięta i musi byc pod jakimś dialogiem
           
            // opcja
           
std::cout << "Dialog: " << dialogue << ", opcja: " << line.substr( tabs + 1 ) << '\n';
       
}
       
else
       
{
           
if( tabs == stack.size() )
           
{
               
if( !dialogue.empty() )
                   
 return false; // druga definicja tego samego dialogu
               
           
}
           
else
            if
( tabs == stack.size() + 1 )
           
{
               
// dialog poziom niżej. Zapisz aktualny na stosie żeby można było do niego wrócić
               
stack.push_back( dialogue );
           
}
           
else
               
 return false; // zbyt głębokie wcięcie
           
           
dialogue = line.substr( tabs );
       
}
    }
   
   
return true;
}

int main()
{
   
if( !parse() )
       
 std::cout << "Blad parsowania\n";
   
}
a
-a1
Dialog: a, opcja: a1
-a2
Dialog: a, opcja: a2
        b
        -b2
Dialog: b, opcja: b2
                c
                -c1
Dialog: c, opcja: c1
                -c2
Dialog: c, opcja: c2
        -b3
Dialog: b, opcja: b3
                d
                -d1
Dialog: d, opcja: d1
-a3
Dialog: a, opcja: a3
W przypadku błędu parsowania, warto by wypisać komunikat błędu (aktualnie napisany tylko w komentarzu) wraz z numerem linii.
P-181225
tBane
Temat założony przez niniejszego użytkownika
» 2024-06-08 02:51:44
dla poniższego dialogu funkcja nie działa. Wyskakuje mi błąd "druga definicja tego samego dialogu"


"W czym mogę pomóc?"
-"Kim jesteś?"
    "Nazywam się Gorn i jestem myśliwym."
-"Na co polujesz?"
    "Głównie na dziobaki oraz wilczury."


"W czym mogę pomóc?"
-"Kim jesteś?"
Dialog: "W czym moge pomóc?", opcja: "Kim jestes?"
"Nazywam się Gorn i jestem myśliwym."
druga definicja tego samego dialogu
Blad parsowania
P-181226
pekfos
» 2024-06-08 13:27:22
U mnie działa. Przykład oczekuje jednego drzewa z dialogiem i poprawnymi wcięciami, konkretnie z użyciem tabulatora. W podanym wyniku wyraźnie nie podawałeś wcięć, bo nic nie jest wcięte. Powinno to wyglądać tak
"W czym mogę pomóc?"
-"Kim jesteś?"
Dialog: "W czym mogę pomóc?", opcja: "Kim jesteś?"
        "Nazywam się Gorn i jestem myśliwym."
-"Na co polujesz?"
Dialog: "W czym mogę pomóc?", opcja: "Na co polujesz?"
        "Głównie na dziobaki oraz wilczury."
P-181227
tBane
Temat założony przez niniejszego użytkownika
» 2024-06-08 18:32:10
ok. Wydaje mi się, że wcześniej poprawnie używałem tabulatorów, ale najważniejsze, że już działa.


"W czym mogę pomóc?"
    -"Kim jesteś?"
        -"Nazywam się Gorn i jestem myśliwym."
    -"Na co polujesz?"
        -"Poluję na dziobaki oraz wilczury"


"W czym mogę pomóc?
-"Kim jesteś?"
Dialog: "W czym moge pomóc?", opcja: "Kim jestes?"
-"Nazywam się Gorn i jestem myśliwym."
Dialog: "W czym moge pomóc?", opcja: "Nazywam sie Gorn i jestem mysliwym."
-"Na co polujesz?"
Dialog: "W czym moge pomóc?", opcja: "Na co polujesz?"

teraz jeszcze mam pytanie, jak opakować to w klasy ? I jak rozróżniać dialogi, bo  getDialogueID(string dialog) jest nieoptymalne chyba

C/C++
class DialogueOption {
public:
   
int nextDialogueID;
   
string text;
   
   
DialogueOption( int nextDialogueID, string text ) {
       
this->nextDialogueID = nextDialogueID;
       
this->text = text;
   
}
}
;

class Dialogue {
public:
   
int id;
   
string text;
   
std::vector < DialogueOption * > options;
   
   
Dialogue( int id, string text ) {
       
this->id = id;
       
this->text = text;
   
}
   
   
addOption( int nextDialogueID, string text ) {
       
options.push_back( new DialogueOption( nextDialogueID, text ) );
   
}
}
;

P-181228
pekfos
» 2024-06-08 21:40:19
A co potrzebujesz rozróżniać? Na pewno musi się dać powiązać NPC z jego dialogiem, co można zrobić przez nazwę pliku. Po wczytaniu będziesz znać nadany ID dialogu dla głównego dialogu drzewa.
P-181229
tBane
Temat założony przez niniejszego użytkownika
» 2024-06-09 01:54:31
Wcześniej miałem dialogi opakowane w 2 klasy. Jedna to była Dialogue i odpowiadała za dialog po stronie NPC, druga zaś to DialogueOption i służyła do wyboru odpowiedzi przez gracza. Teraz zmieniliśmy sposób reprezentacji drzewa dialogu na taki, że wszystkie wypowiedzi zarowno po stronie gracza jak i NPC występujące po głównej wypowiedzi są traktowane jako  DialogueOption i nie wiem jak to opakować w klasy.

id wcześniej było indeksem odpowiedzi po stronie NPC. Teraz id ma być indeksem drzewa dialogu, nie pojedynczej wypowiedzi. Nie wiem w jaki sposób teraz to uporządkować.
P-181230
pekfos
» 2024-06-09 12:34:38
Zmienił się format pliku, nie reprezentacja dialogu w programie. Klasy mogą zostać bez zmian.
P-181231
« 1 » 2
  Strona 1 z 2 Następna strona