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

System Zadań/Misji w grze

Ostatnio zmodyfikowano 2024-08-04 23:18
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
System Zadań/Misji w grze
» 2024-08-02 20:02:20
Witam. Napisałem prosty system zadań/misji w mojej grze 2D RPG. Czy jest to dobra metoda ?

C/C++
#ifndef Quests_hpp
#define Quests_hpp

enum class questCondition { currentHP, showDialogue, haveArmor, haveHelmet, havePants, position_x, position_y };
enum class questState { unstarted, actual, ended };

class Step {
public:
   
questCondition condition;
   
string value;
   
   
Step( questCondition condition, string value ) {
       
this->condition = condition;
       
this->value = value;
   
}
   
   
bool check() {
       
       
if( condition == questCondition::currentHP ) {
           
if( player->HP >= atoi( value.c_str() ) )
               
 return true;
           
       
}
       
       
if( condition == questCondition::showDialogue ) {
           
setDialogue( atoi( value.c_str() ) );
           
return true;
       
}
       
       
if( condition == questCondition::haveArmor ) {
           
if( value == "true" ) {
               
if( player->armor != nullptr )
                   
 return true;
               
           
}
           
           
if( value == "false" ) {
               
if( player->armor == nullptr )
                   
 return true;
               
           
}
        }
       
       
if( condition == questCondition::haveHelmet ) {
           
if( value == "true" ) {
               
if( player->helmet != nullptr )
                   
 return true;
               
           
}
           
           
if( value == "false" ) {
               
if( player->helmet == nullptr )
                   
 return true;
               
           
}
        }
       
       
if( condition == questCondition::havePants ) {
           
if( value == "true" ) {
               
if( player->pants != nullptr )
                   
 return true;
               
           
}
           
           
if( value == "false" ) {
               
if( player->pants == nullptr )
                   
 return true;
               
           
}
        }
       
       
if( condition == questCondition::position_x )
       
{
           
if( abs( player->position.x - atoi( value.c_str() ) ) < 50 ) {
               
return true;
           
}
        }
       
       
if( condition == questCondition::position_y )
       
{
           
if( abs( player->position.y - atoi( value.c_str() ) ) < 50 ) {
               
return true;
           
}
        }
       
       
return false;
   
}
   
}
;

class Quest {
public:
   
int id;
   
string name;
   
questState state;
   
std::vector < Step * > steps;
   
int currentStep;
   
   
Quest( int id, string name ) {
       
       
this->id = id;
       
this->name = name;
       
steps.clear();
       
state = questState::unstarted;
       
currentStep = 0;
       
   
}
   
   
void addStep( questCondition condition, string value ) {
       
Step * step = new Step( condition, value );
       
steps.push_back( step );
   
}
   
   
void check() {
       
       
if( currentStep >= steps.size() - 1 )
           
 state = questState::ended;
       
       
if( steps[ currentStep ]->check() )
           
 currentStep++;
       
   
}
   
   
}
;

std::vector < Quest * > quests;

void loadQuests() {
   
quests.clear();
   
   
Quest * quest1 = new Quest( 0, "Zjedz coś, ubierz się a potem pójdź w wyznaczone miejsce" );
   
quest1->addStep( questCondition::currentHP, "40" );
   
quest1->addStep( questCondition::showDialogue, "13" );
   
quest1->addStep( questCondition::haveArmor, "true" );
   
quest1->addStep( questCondition::haveHelmet, "true" );
   
quest1->addStep( questCondition::havePants, "true" );
   
quest1->addStep( questCondition::showDialogue, "14" );
   
quest1->addStep( questCondition::position_x, "2750" );
   
quest1->addStep( questCondition::position_y, "340" );
   
quest1->addStep( questCondition::showDialogue, "15" );
   
quest1->state = questState::actual;
   
quests.push_back( quest1 );
   
   
   
}

void checkQuests() {
   
   
for( auto & quest: quests ) {
       
       
if( quest->state == questState::actual ) {
           
quest->check();
           
       
}
       
    }
   
}


#endif
P-181387
pekfos
» 2024-08-03 18:25:19
To bardziej Quest pasuje do "kroku" w zadaniu, bo te warunki to chyba powinny być wszystkie spełnione naraz? Te przykładowe zadanie mówi że masz założyć przedmioty (możesz od razu zdjąć), następnie udać się na pozycję x~2750, potem y~340, niekoniecznie naraz. Więc jeśli ma tam na ciebie czekać zasadzka, to własną pozycję X możesz wybrać tak by cię tam akurat nie było. Nie takie exploity już gracze znajdowali.
Poza tym te zadania są z definicji liniowe. Jeżeli dialog ma tu jakieś opcje, to musiałby być ostatni w zadaniu i aktywować jedno z możliwych kontynuacji zadań i to w każdym możliwym przypadku, inaczej zadanie urwie się bez możliwości wznowienia.

C/C++
if( condition == questCondition::havePants ) {
   
if( value == "true" ) {
       
if( player->pants != nullptr )
           
 return true;
       
   
}
   
   
if( value == "false" ) {
       
if( player->pants == nullptr )
           
 return true;
       
   
}
}
A jak nie będzie ani jedno ani drugie, to kicha? Powinieneś już wiedzieć lepiej niż kopiować kod, to powinno wyglądać tak:
C/C++
if( condition == questCondition::havePants ) {
   
return compareConditionBoolean( value, player->pants != nullptr ); // bool compareConditionBoolean(string, bool)
}
P-181388
tBane
Temat założony przez niniejszego użytkownika
» 2024-08-04 14:48:13
Jak nie będzie ani jedno ani drugie wtedy zwraca false. Position_x i position_y zastąpiłem zwykłym position.
C/C++
quest1->addStep( questCondition::position, "2750 340", L"powinienem iść wzdłóż ścieżki" );
P-181399
pekfos
» 2024-08-04 22:46:40
Jak nie będzie ani jedno ani drugie wtedy zwraca false.
Czyli kicha, bo warunek jest zawsze fałszywy i pewnie wyjdzie to dopiero w praniu. Nigdy nie polegaj na tym że napis nie będzie miał żadnego typo, bo będzie miał. Od zachowania programu w tym przypadku będzie zależało jak długo będziesz tego szukał. Najlepiej jakby jakiś parser sprawdzał czy napis ma jedną z poprawnych wartości, wtedy wiadomo od razu że jest błąd i gdzie. A jak quest po prostu i po cichu nie zadziała jak dojdziesz do konkretnego punktu, to znacznie gorzej.
P-181403
tBane
Temat założony przez niniejszego użytkownika
» 2024-08-04 22:57:26
Nie rozumiem. Na końcu funkcji ustawiłem return false na wypadek, gdyby żaden z warunków nie został spełniony.

C/C++
bool check() {
   
   
// ...
   
   
if( condition == questCondition::havePants ) {
       
if( value == "true" ) {
           
if( player->pants != nullptr )
               
 return true;
           
       
}
       
       
if( value == "false" ) {
           
if( player->pants == nullptr )
               
 return true;
           
       
}
    }
   
   
// ...
   
   
return false;
}
P-181404
pekfos
» 2024-08-04 23:09:35
Jak się zachowa gra jak havePants będzie miało warunek "flase"? I nie mam na myśli że "zwrócisz false - o, tutaj", tylko jak się gra zachowa jako całość. Bo mi to wygląda na soft lock.
P-181405
tBane
Temat założony przez niniejszego użytkownika
» 2024-08-04 23:18:38
Wtedy, quest się dalej nie wykona, bo zwróci false w funkcji check()
P-181406
« 1 »
  Strona 1 z 1