Alors il y a effectivement ce que propose geogeo, à savoir une liste statique d'événements prédéfinis pour chaque quête. Si ça ne te suffit pas, tu peux peut-être faire un truc style OS multitâche coopératif, avec des sémaphores (attente bloquante) :
void QueteDuPont() {
if (!map[mypont.pos].is_destroyed)
wait(map[mypont.pos].destroyed);
while (money<42)
wait(money_changed);
}
L'intérêt étant que si tu as une map gigantesque, le thread QueteDuPont ne ralentira le programme que si tu touches au pont en question...
Le problème, c'est par contre que tu peux oublier de wait()er sur un sémaphore, et du coup tu peux avoir des bugs subtils qui font qu'une quête "oubliera" de s'accomplir dans certains cas tordus... Ca peut être très difficile à trouver (et particulièrement frustrant pour le joueur qui se retrouve bloqué sans comprendre pourquoi

), donc il faut peut-être réfléchir à un système qui, "by design" ne serait pas sujet à ce genre de bugs.
Par exemple tu peux faire en sorte qu'aucune variable globale ne soit directement accessible, et qu'il faille passer par un wrapper qui logge les accès :
void QueteDuPont_VerifierAccomplissement() {
int pont = getvar(pont_a_detruire);
if (getmap(getobjectposition(pont))!=PONT)
return;
if (getvar(player_money)<42)
return;
QueteDuPont_Accomplir();
}
L'idée c'est que tu exécutes une fois chaque vérification de quête entièrement au début du programme, puis tu notes de quelles variables elle dépend, et enfin si une de ces variables changent tu réexécutes la quête. En l'occurrence si le pont à détruire change, ou que sa position change, ou que le contenu de la map à cet endroit change, la quête est rappelée. Si ensuite le pont est effectivement détruit (et seulement dans ce cas-là), la quête sera rappelée quand l'argent du joueur change, jusqu'à ce que la quête soit réalisée. Bref, pas moyen de se planter (à moins d'introduire du non-déterminisme), et ça m'a l'air plutôt efficace.
Ca donnerait un code du style :
/* context est une variable globale identifiant la quête : c'est utile pour qu'on sache comment la rappeler */
int getvar(Var *ptr) {
if (!list_contains(ptr->references,context))
list_add(ptr->references,context);
return ptr->value;
}
int getmap(int pos) {
Var *ptr = &map[pos];
if (!list_contains(ptr->references,context))
list_add(ptr->references,context);
return ptr->value;
}
void notifyvar(Var *ptr) {
foreach (context,ptr->references) {
if (!list_contains(need_reexecute,context))
list_add(need_reexecute,context);
}
list_clear(ptr->references);
}
void setvar(Var *ptr,int newvalue) {
notifyvar(ptr);
ptr->value = newvalue;
}
void setmap(int pos,int newvalue) {
notifyvar(map);
notifyvar(&map[pos]);
ptr->value = newvalue;
}
/* à appeler à chaque tour */
void ReexecuterLesQuetes() {
foreach (mycontext,need_reexecute) {
context = mycontext;
list_del(need_reexecute,context);
context->callback();
context = NULL;
}
}