Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » Adoranda : Un Aventura-like rafraîchissant
Tituya Hors ligne Rédacteur Points: 1962 Défis: 16 Message

Adoranda : Un Aventura-like rafraîchissant

Posté le 10/08/2021 00:44

Salut !

C'est l'été (malgré la météo quelque peu désagréable), et été rime avec projet pour moi !

Comme vous avez peut-être pu le voir, j'ai commencé depuis peu un nouveau projet grandement inspiré de Aventura, le Royaume Poudingue (dont je vous invite à aller voir le Press Shift)

Alors non ce ne sera pas un remake, juste un jeu répondant aux mêmes principes c'est à dire :
Une grande carte accessible dès le début
La possibilité de progresser comme on le souhaite
Pouvoir xp d'une certaine façon

Je n'ai pas encore une idée bien claire du gameplay ou de l'histoire, mais je suis dans l'optique de faire un jeu avec un univers propre et détaillé. C'est pour cela que j'ai rajouté des personnages avec qui vous pouvez discuter

Au niveau développement, j'ai privilégié le côté esthétique au technique :
Les cartes sont créées avec Tiled et peuvent posséder 2 layers.
Les collisions/objets sont indiquées directement dans le tileset grâce aux valeurs de Tiled. Il n'y a donc rien de plus simple que de définir un mur !
Le joueur est constamment affiché au centre à la manière d'un jeu pokémon. La carte est donc affichée autour du joueur et non pas l'inverse.
Le joueur est animé.
Des personnages peuvent être dissimilés partout sur la carte avec des dialogues uniques. (Vous n'êtes pas à l'abri d'apparaître dans le jeu sauf refus catégorique )

Au niveau de ce que je souhaite rajouter :

Un intérieur (aléatoire ?) des maisons
Des capacités et de quoi xp
La carte sera divisée en 4 parties. Une par saison selon mes prévisions.
Une sauvegarde évidemment
Un tileset complet, pour l'instant c'est une partie de celui de pokémon rouge feu
Et des choses en plus, je ne vais quand même pas tout raconter !

Ce projet est avant tout un moyen d'apprendre le C et de découvrir les fabuleux outils de Lephenixnoir. Notamment fxconv qui est juste génial
Je vais donc continuer tranquillement le développement du jeu en essayant de donner des nouvelles de temps en temps. Pour vous teaser, voici une panoplie de screenshots de l'état actuel du projet (la carte sert de test, je ne compte pas la garder) :




Voilà le git du projet si vous souhaitez suivre le développement : https://github.com/bgiraudr/Adoranda

Hope you enjoy

@RDP <- C'est drôle, je me donne du travail pour dimanche


Fichier joint


Lephenixnoir En ligne Administrateur Points: 22261 Défis: 149 Message

Citer : Posté le 25/01/2022 09:36 | #


Super ! Pour les monstres tu as un plan graphique quelque part ? Je me demandais s'il y avait pas moyen de trouver des sprites dans des fangames Pokémon à un moment. Ou alors peut-être que tu veux les faire toi-même ?
Tituya Hors ligne Rédacteur Points: 1962 Défis: 16 Message

Citer : Posté le 25/01/2022 16:58 | # | Fichier joint


J'ai bien envie d'essayer d'en faire par moi-même. Même si ça risque d'être difficile je n'ai pas besoin d'en avoir 50 différents.
Par contre je ne pense les animer, déjà je trouve les animations complexes à faire (en termes de programmation + niveau dessin), de plus cela risque de prendre beaucoup de places.
Si je n'y arrive pas j'irais chercher des idées dans des fangames
Bretagne > Reste du globe
(Et de toute façon, vous pouvez pas dire l'inverse grâce à Bzh)
Projet en cours : Adoranda

Mes programmes
Hésite pas à faire un test !


Lephenixnoir En ligne Administrateur Points: 22261 Défis: 149 Message

Citer : Posté le 11/02/2022 20:50 | #


Ahah ! Je suis dans le jeu !
Tituya Hors ligne Rédacteur Points: 1962 Défis: 16 Message

Citer : Posté le 13/02/2022 22:48 | # | Fichier joint


Lephenixnoir a écrit :
Ahah ! Je suis dans le jeu !

Et bientôt tu seras un monstre !

Je réveille un peu ce topic suite à de récentes mises à jour liées aux combats. Je me rends compte à l'instant que je n'en ai jamais parlé ici.
J'ai adopté des combats au tour par tour à la manière de pokémon. Retenez bien que mon "à la manière de" représentant un "c'est une copie de pokémon".

Tout d'abord voici un aperçu de l'environnement de combat :


Un environnement très simple se permettant juste de lister vos différentes attaques. Comme pour un jeu pokémon vous et votre adversaire possédez des statistiques. Et c'est là que je vais pouvoir détailler.

Les statistiques

Les statistiques actuelles sont simples, elles regroupent :
Attaque
Défense
PV
Niveau
XP

Un monstre est défini dans un fichier json ressemblant à ceci :
{
    "name":"test",
    "sprite":"test",
    "stats":{
        "atk":10,
        "def":50,
        "pv":20,
        "level":1,
        "xp":300,
        "max_pv":20
    },
    "moves":[
        0,
        1,
        2
    ]
}

Les monstres possèdent donc un movepool lié à l'identifiant des différentes attaques.

Ces statistiques ne sont pas des valeurs "brutes". Il s'agit en fait d'une base servant à définir la puissance d'un monstre en fonction de son niveau. Voici la formule régissant l'évolution de ces statistiques.

((2 * base + niveau / 4 + 100) * niveau) / 100 + 10

base : Valeur de base de la statistique de ce monstre
niveau : Niveau souhaité du monstre

Ainsi prenons le monstre situé plus haut. Son niveau de point de vie va donc suivre la courbe en rouge, son niveau de défense la courbe en bleu :


Le joueur est régi par la même croissance.

Les statistiques c'est mignon, mais concrètement elles servent à quoi ?
Voici la formule du calcul des dégâts :

((2*niveau / 5 + 2) * attaque_attaquant * attaque_capacité / défense_cible) / 50 + 2

niveau : niveau de l'attaquant
attaque_attaquant : statistique de l'attaque de l'attaquant
attaque_capacité : taux de dégât de la capacité
défense_cible : statistique de défense de la cible

Pas de courbe ici, prenons un exemple.
Nous avons la capacité "Charge" avec 45 de dégâts. Notre monstre est au niveau 10 et possède donc une statistique d'attaque de 22. Admettons que la cible a une stat de défense de 10.

La capacité va donc infliger : 13.88 arrondis à 13 HP.

Si la cible avait une défense telle que notre monstre (base de 50 = 30 à ce niveau) l'attaque aurait infligée seulement 5 HP.

Ok très bien mais comment le niveau du joueur est défini ?

En vainquant un monstre vous gagnez de l'expérience, cette expérience est calculée de cette manière :

(base_xp * niveau_vaincu * 1.5) / 7

base_xp : Le taux d'expérience que le monstre donne (dans l'exemple 300)
niveau_vaincu : Le niveau du monstre vaincu

Eh oui, deux monstres ne vont pas forcément rapporter la même quantité d'expérience. En fonction de la base d'expérience, vous allez gagner plus ou moins d'expérience.
Cette expérience permet d'augmenter votre niveau de cette manière :

expérience_totale^0.33

En gros, un équivalent de la racine cubique de l'expérience.

Voilà qui fait beaucoup de formules différentes, mais globalement cela permet d'avoir une progression plutôt agréable
Bien sûr il faut encore faire des ajustements sur les différents coefficients, mais maintenant nous pouvons améliorer notre joueur et ça c'est déjà quelque chose de bien !

Voilà voilà, j'ai pu aussi travailler sur d'autres petits trucs. Mais l'ajout principal reste cette gestion des statistiques
À bientôt !
@RDP
Bretagne > Reste du globe
(Et de toute façon, vous pouvez pas dire l'inverse grâce à Bzh)
Projet en cours : Adoranda

Mes programmes
Hésite pas à faire un test !


Tituya Hors ligne Rédacteur Points: 1962 Défis: 16 Message

Citer : Posté le 15/02/2022 02:20 | # | Fichier joint


Je me suis motivé un peu et ai commencé à travailler sur l'interface en combat. Sans trop de surprise on dirait un jeu pokémon. Décidément, je me demande ce que je suis en train de faire

En tout cas vous pouvez comparer, quand l'interface est agréable ça donne directement beaucoup plus envie !



Avant c'était ça ahah


Bretagne > Reste du globe
(Et de toute façon, vous pouvez pas dire l'inverse grâce à Bzh)
Projet en cours : Adoranda

Mes programmes
Hésite pas à faire un test !


Lephenixnoir En ligne Administrateur Points: 22261 Défis: 149 Message

Citer : Posté le 15/02/2022 10:28 | #


C'est solide ! C'est marrant que tu sois parti en mode full Pokémon sur les combats, ça permettra de récupérer les mécaniques
Tituya Hors ligne Rédacteur Points: 1962 Défis: 16 Message

Citer : Posté le 28/02/2022 12:05 | # | Fichier joint


Je suis en train de rédiger la RDP, j'ai besoin d'une image.

J'ai pu rajouter un système de "zone" directement sur la carte Tiled. Avec ses rectangles il est très facile de donner le niveau moyen d'une zone ainsi que de spécifier les monstres que le joueur risque de rencontrer (probabilité égale).


J'ai également pu rajouter deux trois petites choses que vous pourrez voir dans la revue

Ajouté le 27/03/2022 à 01:51 :
Yo vous vous souvenez de ce topic ?

Aujourd'hui, pour changer un peu ce n'est pas pour annuler le projet que j'envoie un message mais plutôt pour vous demander deux choses :

1 - Quelles mécaniques de combat souhaitez-vous en priorité ?

En effet pour l'instant je n'ai pas implémenté énormément de choses, à vrai dire il n'y a que des attaques physiques et des attaques pour améliorer ses statistiques le temps d'un combat.
Voulez-vous, à la manière d'un pokémon (quitte à copier jusqu'au bout), un système de type ou encore un système d'attaque spéciale et défense spéciale sur des statistiques différentes ?
Au niveau contenu de combat j'ai aussi rajouté les coups critiques (probabilité 1/16) et une chance de rater son attaque en fonction de la précision.

Et voilà la question intéressante :
2 - Comment implémenter le système d'évènements ?

Quand je parle d'évènement je parle des actions que certains pnj / objets / interactions peuvent vous donner. Genre parler avec quelqu'un qui vous apprend une capacité ou trouver un objet sur le sol qui vous améliore vos stats.

Vu que je n'ai jamais programmé de RPG je ne sais pas trop comment gérer ça, j'ai pensé à un système qui me plaît plutôt bien et reste simple à mettre en place :
Un attribut "event" sur chacun des éléments pouvant avoir un évènement. Lié à un identifiant et 0 si aucun évènement.
Et un simple appel vers une fonction spécifique qui redirige vers le bon évènement programmé en dur dans le code.

J'aime bien cette solution, mais à voir si vous avez des propositions plus intéressantes et moins programmé en "dur"

Au niveau du changelog depuis la dernière fois :
• Fix dialogue (merci Lephé)
• Les zones peuvent contenir plusieurs monstres qui apparaissent tous de manière aléatoire.
De ce côté il s'agit juste d'un attribut "monster" dans les zones avec les identifiants des monstres en question sous cette forme : id;id;id. Pour me simplifier la vie j'ai aussi cette syntaxe : id1-id2;id3 avec id1 et id2 un range entre deux monstres.
Pour les probabilités d'apparition on peut simplement rajouter plusieurs fois un même id pour augmenter sa probabilité d'apparition.
• Le joueur apprend des capacités en montant de niveau.

Et voilà, c'est tout
Bretagne > Reste du globe
(Et de toute façon, vous pouvez pas dire l'inverse grâce à Bzh)
Projet en cours : Adoranda

Mes programmes
Hésite pas à faire un test !


Kikoodx Hors ligne Labélisateur Points: 2969 Défis: 11 Message

Citer : Posté le 27/03/2022 03:51 | #


Salut Tituya, je suis un believer.

1 - Quelles mécaniques de combat souhaitez-vous en priorité ?

Quelles mécaniques de combat as-tu absolument besoin pour que le jeu fonctionne ? Conserve celles-ci et jette le reste (ou au moins met le de côté pour bien plus tard), ça ne te servira à rien d'avoir un combat ultra complet si le contenu n'en a pas besoin (sauf si ton jeu est centré autour du combat évidement, mais dans ce cas tu ne poserais pas cette question). Ce conseil s'applique également aux statistiques.

2 - Comment implémenter le système d'évènements ?

J'ai une proposition à te faire. Il y a peut-être mieux, mais il y a aussi bien pire.

Les événements peuvent être déclarés dans une structure contenant les informations associées : le type, que tu as mentionné, et d'autres attributs propres à certains événements (contenus dans des unions).

enum EventType { ET_NONE, ET_XP, ET_DEATH, ET_SAY, ET_GIVE };

union EventArg {
    int i;
    char *s;
};

struct Event {
    unsigned int type;
    union EventArg a, b, c;
};


Tu as la possiblité de déclarer des listes de struct Event terminéees un ET_NONE pour rendre leur parcours facile :
static const struct Event have_a_nice_death[] = {
    { ET_XP, 69 },
    { ET_SAY, {.s = "Nice!"} },
    { ET_GIVE, 42, {.s = "gold"} },
    { ET_DEATH },
    { 0 },
};

Tu peux process les événements dans un switch (event.type).

J'espère que ça te donne une idée.

J'attend de voir les propositions d'autres personnes, je suis curieux.

#TituyaAdmin
mi lape ala.
Massena En ligne Rédacteur Points: 2088 Défis: 11 Message

Citer : Posté le 27/03/2022 10:20 | #


Au niveau du système de combat, j'ai un faible pour celui d'Omori (très inspiré de Pokemon) qui est très simple mais diablement efficace.

En gros, il y a trois types basés sur les émotions :
– Joie, qui augmente la rapidité et la chance mais diminue la puissance des coups. Fort contre Colère.
– Colère, qui augmente les dégats mais diminue la défense. Fort contre Tristesse.
– Tristesse, qui augmente la défense et diminue la vitesse, et "tank" une partie des dégats vers les points de magie. Fort contre Joie.
– Neutre, l'état par défaut.

À noter que les émotions se déclinent en trois variations de plus en plus puissantes (angry → enraged → furious) qui accentuent leurs propriétés. Là où c'est intéressant c'est que les personnages et les ennemis ont des attaques spéciales qui permettent de modifier les émotions d'une ou plusieurs personnes afin de le tourner à son avanatage : Par exemple, le perso A peut énerver le perso C, le perso B peut rendre triste l'ennemi et le perso C frapper : grâce aux changements d'état il inflige plus de dégâts. L'avantage c'est qu'on rentre dans des combats beaucoup plus dynamiques vu que le type n'est pas figé et que l'ennemi peut emmêler nos émotions aussi

(Combats d'autant plus dynamiques qu'il y a des follow-up, c'est-à-dire des attaques supplémentaire QTE qui consomment des points spéciaux et qui ont pleeein d'effets mais je développerai pas là-dessus )

Bien évidemment si tu reprends ce système faudra tout changer pour pas copier, mais le concept est là. Sinon, dans l'absolu fait ce qu'il te plaît
Lephenixnoir En ligne Administrateur Points: 22261 Défis: 149 Message

Citer : Posté le 27/03/2022 10:54 | #


1 - Quelles mécaniques de combat souhaitez-vous en priorité ?

Personnellement je pense que l'approche full Pokémon se vaut bien ; si tu regardes le système Gen 1. c'est pas monstrueux ; t'as 5 stats, des types sur les mon et les attaques, 2 types d'attaques, buffs et STAB. En tous cas ça te donnerait une répartition conception/implémentation très orientée implem, donc si tu sèches sur le design ça peut être cool.

2 - Comment implémenter le système d'évènements ?

Perso j'ai encore moins symbolique que KikooDX. Le "piège" avec l'approche de KikooDX (un peu rencontré dans Rogue Life) c'est que y'a potentiellement pléthore d'événements très variés et une fois que tu es commit à une enum + un switch t'es un peu obligé de faire un type pour chacun.

Je représenterais un événement par une chaîne de caractères. Certaines seraient génériques comme "give:poke_ball*20" et d'autres seraient très au cas-par-cas comme "special:old_man_demo". De cette façon, tu pourrais pas exemple les intégrer aux dialogues si, disons, le premier caractère de la section soit ~ (au hasard pur). Par exemple, le dialogue

"Salut, voilà 20 Poké Balls !;~give:poke_ball*20;Ne me remercie pas !"

Pour gérer les événements je mettrais une fonction très générique qui a accès à l'information complète du jeu (game_t *game représente ça). Tu pourrais alors traiter les événements génériques de façon générique (ce qui te permet d'en ajouter dans le jeu sans le recoder à chaque fois) et les événements spéciaux comme bon te semble (avec peu d'overhead, juste un test en plus).

// Renvoie un bool pour dire si on a réussi
bool handle_event(game_t *game, char const *event)
{
    if(!strncmp(event, "give:", 5)) {
        event += 5;
        // Isoler le nom et la quantité
        int len=strlen(event), qty=1;
        char *star = strchr(event, '*');
        if(star) len=star-event, qty=atoi(star+1);
        // Trouver l'item et la donner au joueur
        item_t item = get_item_by_name(event, len);
        // Peut échouer (inventaire plein)
        return player_give_item(item, qty);
    }
    // ...

    else if(!strcmp(event, "special:old_man_demo")) {
        game->start_battle(demo_battle);
        // etc, n'importe quoi de compliqué
        return true;
    }
}

J'ai pas pris en compte le fait que selon les cas il faut "désactiver" l'événement ici. Mon idée ce serait que tu as un événement pour faire avancer les dialogues/l'histoire et donc si tu veux te débarrasser de la ligne de dialogue qui donne des Poké Balls tu changes le dialogue avec le mécanisme classique pour le scénario (contrôlé par un événement, potentiellement).
Tituya Hors ligne Rédacteur Points: 1962 Défis: 16 Message

Citer : Posté le 10/05/2022 17:00 | # | Fichier joint


Hey vous vous souvenez de ce topic ?
Comment ça non... Pourtant je fais de mon mieux pour le garder actif, regardez la date du dernier mess- Ouais finalement non, ne regardez pas

Bon, depuis la dernière fois j'ai pu avancer un peu, rien de bien méchant mais c'est important de le noter quelque part :

Évènements

Le système proposé juste au dessus par Lephenixnoir est vraiment performant et permet une grande flexibilité. Implémenté directement dans les dialogues, on a la possibilité de réaliser n'importe quelle action à partir d'un dialogue banal. C'est vraiment intéressant.

Pour l'instant 3 actions peuvent provoquer des évènements :
  • Les dialogues en tout genre (Personnage, pancartes...)
  • Les zones. Au passage dans une zone un évènement peut être lancé. Pratique pour faire avancer l'histoire
  • Les items dans l'inventaire du joueur.

Je reviendrais après le changelog sur les évents. J'ai quelques problèmes et j'aimerais bien votre avis
Merci encore à lephé pour cette idée de qualité

Items et inventaire

Je parlais plus tôt des items et de l'inventaire du joueur. En effet à présent le joueur possède à présent son propre inventaire limité à 30 places.
L'inventaire n'est pas infini. Dans le sens où lorsqu'un item de même nature est ajouté il occupe une place supplémentaire. Il ne se "stack" pas aux autres.

Chaque item est défini par son fichier Json suivant cette forme :
{
    "name":"Test1",
    "id":1,
    "sprite":"item",
    "description":"Redonne 20HP",
    "action":[
        "pp:all",
        "give:Obj2*3"
    ]
}

Avec un sprite, sa description et sa liste d'évènements qui seront lancés lors de sa sélection.
Comme tout inventaire, vous pouvez consulter vos objets, en supprimer ou encore en remplacer si vous n'avez plus de place. Rien de particulier ni de mystique de ce côté là.

Pour l'instant voici ce à quoi il ressemble. Attention vous allez être surpris devant tant de beauté


Types

Un jeu tour par tour sans système de type = un jeu où celui qui possède la plus grosse attaque gagne à coup sûr.
J'ai donc implémenté un système de type à la pokémon (étonnant non ? )

Je n'ai pas encore de liste de type. Ça va dépendre de la tournure de l'histoire (@Shadow15510). Pour l'instant j'ai réalisé des tests sur des rôles sur le forum.
En tout cas il y a 4 réactions possibles aux types :

  • Super efficace -> *2 sur la puissance de base de l'attaque
  • Efficace -> Rien de particulier
  • Peu efficace -> *0.5 sur la puissance de base de l'attaque
  • Non efficace -> 0


Les monstres, le joueur ainsi que les attaques possèdent donc un type (un seul pour éviter des petits problèmes). En fonction de la table des types, les différents coefficients sont appliqués.
Il y a également un système de STAB. Si le lanceur possède le même type que l'attaque qu'il lance, il profite d'un buff de *1.5 sur la puissance de l'attaque.

La table des types est présentée sous la forme d'un fichier CSV (une grille en gros). Avec comme abscisse le type en défense et en ordonné le type attaquant.

┌────────────────┬────────────────┬─────────────┬────────────┬───────────────┐
│ type           │ Administrateur │ Modérateur  │ Rédacteur  │ Labélisateur  │
├────────────────┼────────────────┼─────────────┼────────────┼───────────────┤
│ Administrateur │ 0              │ 1           │ 1          │ 2             │
│ Modérateur     │ 0              │ 0,5         │ 2          │ 2             │
│ Rédacteur      │ 2              │ 1           │ 0,5        │ 1             │
│ Labélisateur   │ 2              │ 0,5         │ 1          │ 0             │
└────────────────┴────────────────┴─────────────┴────────────┴───────────────┘


Il est donc très simple de lire les faiblesses des différents type ainsi que de les modifier

Le type du joueur va pouvoir être changé au fil de l'aventure à l'aide de pnjs placés sur la carte. Vous obligeant à parcourir le monde avant de faire certaines parties trop dure

Autre

Le joueur possède deux stats de plus : attaque spéciale et défense spéciale. Il y a donc un nouveau type d'attaque permettant de taper sur le physique ou sur le spécial. Ça amène plus de diversité dans les combats

Voilà, c'est un peu prêt tout pour les modifications importantes sur le projet. À présent place aux problèmes mais dans un futur message, je n'ai pas trop le temps de l'écrire maintenant.
Il reste encore des choses à faire, mais théoriquement à l'aide du système d'évènement le jeu peut bientôt être commencé. Il faut également qu'on se mette d'accord sur un scénario, mais à ce niveau je compte un peu sur Shadow et ses idées magistrales !

@RDP, ça fait longtemps qu'on a pas parlé d'un projet simple

Ajouté le 10/05/2022 à 20:36 :
OK, j'ai un peu plus de temps place aux questions.

1 - Les évènements doivent être désactivés après leur activation.
Concrètement il faut enregistrer dans la structure du joueur quelque chose permettant d'identifier de manière sûre l'évènement. Je ne peux pas vraiment ajouter un identifiant unique à un event à cause de son fonctionnement de base (sous forme de string, pas ). Alors je reste à votre disposition concernant cette mécanique.
On en avait plus ou moins parlé sur la shout, concernant un hash notamment. Le mieux c'est d'en reparler de manière claire et durable sur le topic


2 - J'ai un petit problème concernant les évènements et les zones.
Bon, vous commencez à me connaître j'ai souvent des problèmes un peu basiques à cause de mon manque d'expérience en C

Bon, alors les Zones sont définies par cette structure :

struct Zone {
    int start_x, start_y, end_x, end_y;
    char *event; // le string lié aux évenements à lancer lors de l'arrivée dans la zone
    int level;
    int nbMonsters;
    short *monsters; // un tableau comportant les identifiants des monstres qui peuvent spawn dans la zone
};

Donc chacune des cartes possèdent sa liste de zone. Ainsi nous avons cette définition par carte :

struct Map {
    int zone_count;
    struct Zone *zones;
};

Ok à présent place aux problèmes

Les cartes sont converties grâce à fxconv, et c'est là qu'il y a sûrement un problème. Voici la méthode responsable de la conversion des zones :

def parseZone(layer):
    zone = fxconv.Structure()
    for i in layer["objects"]:
        origin = (int(i['x']/16), int(i['y']/16))
        to = (int(origin[0]+i['width']/16)-1, int(origin[1]+i['height']/16)-1)

        zone += fxconv.u32(origin[0])
        zone += fxconv.u32(origin[1])
        zone += fxconv.u32(to[0])
        zone += fxconv.u32(to[1])
        zone += fxconv.string(i["properties"][0]["value"]) #event

        monsters = bytes()
        zone += fxconv.u32(int(i["properties"][1]["value"]) if i["properties"][1]["value"] != "" else -1) #level
        monster_list_raw = []
        if i["properties"][2]["value"] != "":  monster_list_raw = i["properties"][2]["value"].split(";") #monster list
        monster_list = []
        #x-y notation generate an array
        for i in monster_list_raw:
            if "-" in i:
                a = i.split("-")
                monster_list.extend(list(range(int(a[0]),int(a[1])+1)))
            else:
                monster_list.append(int(i))
        zone += fxconv.u32(len(monster_list))

        print(f"zone {origin}:{to}")
        for j in monster_list:
            print(int(j))
            monsters += fxconv.u16(int(j))

        zone += fxconv.ptr(monsters)
    return zone

Aucun problème au niveau de la détection des monstres dans la carte, ils sont correctement placés dans le tableau monster_list.
Avant de les rajouter dans la map en question à l'aide d'un simple :

zone = fxconv.Structure()
nbZone = len(layer["objects"])
zone = parseZone(layer)
structMap += fxconv.ptr(zone)

Enfin bref. Depuis que j'ai rajouté le char * lié aux évènements, j'ai une erreur mémoire sur l'accès au tableau des monstres dans l'ensemble des zones excepté sur la dernière compilée.

Le nombre de monstre est bien défini, le string lié à l'évènement aussi. Juste l'accès au tableau provoque une magnifique erreur système.
Je suppose que le tableau n'est pas bien généré, si je me rend dans une zone (contenant des monstres ça c'est sûr et vérifié) et que je lance un simple

get_zone(game->player, game->map).monsters[0]


L'erreur est provoquée. Preuve d'un tableau malformé.
Actuellement je n'ai pas forcément d'idée concernant l'origine de ce problème, le seul truc que je sais c'est qu'en enlevant le char* il n'y a aucun problème. Et que la dernière zone compilée possède correctement le tableau de monstres.
Si vous avez une idée je suis preneur.

merci
Bretagne > Reste du globe
(Et de toute façon, vous pouvez pas dire l'inverse grâce à Bzh)
Projet en cours : Adoranda

Mes programmes
Hésite pas à faire un test !


Kikoodx Hors ligne Labélisateur Points: 2969 Défis: 11 Message

Citer : Posté le 10/05/2022 22:48 | #


Content de voir que tu progresses

La question 2 j'en ai aucune idée (je sais pas utiliser fxconv), je peux tenter la 1.

Trouve une bonne fonction de hash (j'ai vu djb2 après quelques recherches). Crée un tableau. Quand tu exécutes un dialogue, vérifie si le hash se trouve dedans, si c'est le cas lance les événements sinon place le hash à la fin du tableau. Si t'as besoin de sauvegarder, dump le contenu du tableau dans un fichier.
mi lape ala.
Lephenixnoir En ligne Administrateur Points: 22261 Défis: 149 Message

Citer : Posté le 11/05/2022 08:59 | #


1 - Les évènements doivent être désactivés après leur activation.

Parfois ce sera évident pour une raison externe : un objet va être consommé après avoir été activé, les statistiques de l'histoire vont évoluer et désactiver des interactions sur la map, ou les personnages vont changer de dialogues.

Une des options vraiment triviales c'est de faire en sorte que chaque dialogue contenant un événement unique soit remplacé après son exécution, en utilisant le même mécanisme que pour faire avancer l'histoire. Et ce, quitte à avoir les mêmes répliques mais avec l'événement retiré (ce que tu peux peut-être générer automatiquement).

Une autre idée naturelle c'est d'avoir un identifiant unique pour traquer le statut de chaque événement qui doit être unique, et noter d'une façon ou d'une autre lesquels ont déjà été exécutés.

J'avoue que j'ai du mal à faire confiance à une fonction de hash "triviale" pour un truc comme ça ; y'a plein de collisions et je sais pas exactement quelle est la probabilité que ce soit un problème vs. le bordel pour le debugger.

Vue la quantité d'informations que tu vas avoir à stocker de toute façon pour suivre la progression du joueur dans l'histoire, les interactions réalisées, etc. je serais plutôt tenté de stocker là-dedans. Par exemple, je stockerais plutôt l'information par-PNJ, pour lesquels tu as sans doute déjà un identifiant unique.

2 - J'ai un petit problème concernant les évènements et les zones.

Ça a l'air correct de loin. Je n'ai pas le temps de tester en détail, mais je me demande si ce serait pas un problème de référence sur fxconv.ptr(monsters) dans fxconv. Est-ce que tu saurais voir si les données sont correctes en désassemblant ?
Tituya Hors ligne Rédacteur Points: 1962 Défis: 16 Message

Citer : Posté le 31/05/2022 00:20 | # | Fichier joint


En relisant un peu ce topic je me rends compte que je n'ai pas montré la nouvelle tête de l'inventaire. À la manière de mon précédent message sur les combats je vous montre un petit avant-après du nouvel inventaire

C'est dingue comment il suffit de faire un design pour changer totalement l'aspect "finition" du jeu.



Il n'y a rien de particulier concernant cet inventaire, suite à quelques plaintes de la part de mes collègues je me demande si je ne vais pas instaurer un système de tri par nom dans l'inventaire. À voir si c'est intéressant
Petit détail qui a son importance, vous ne pouvez pas utiliser un item s'il ne provoque aucune modification. Si vous avez l'ensemble de vos points de vies, prendre une potion ne va servir à rien et le jeu vous l'indique.

Si vous voyez des informations à rajouter dans l'inventaire je suis preneur. Je le trouve globalement assez complet pour l'instant et j'aime beaucoup le design que j'ai réussi à lui donner.

J'ai quelques petits ajouts à droite et à gauche qui sont intéressants, je vais essayer de préparer une petite démo du moteur histoire de vous montrer ce qu'il est possible de faire à présent. Restez au courant !
Bretagne > Reste du globe
(Et de toute façon, vous pouvez pas dire l'inverse grâce à Bzh)
Projet en cours : Adoranda

Mes programmes
Hésite pas à faire un test !


Massena En ligne Rédacteur Points: 2088 Défis: 11 Message

Citer : Posté le 31/05/2022 07:12 | #


Ow elles sont jolies ces potions :3
Tu comptes mettre quoi dans la section du dessous ?
Lephenixnoir En ligne Administrateur Points: 22261 Défis: 149 Message

Citer : Posté le 31/05/2022 08:41 | #


Jolies potions ouais, tu les as faites à la main ? :o

La ligne parallèle tout en bas à droite contribue beaucoup à la structure à mon avis, mais il m'a fallu longtemps pour la voir. Il y a peut-être moyen de la mettre plus en valeur sans grignoter trop d'espace ?
Tituya Hors ligne Rédacteur Points: 1962 Défis: 16 Message

Citer : Posté le 31/05/2022 09:20 | #


Alors je vais vous décevoir mais non, je n'ai pas fait les potions à la main. Elles sortent tout droit de ce site je me suis juste occupé de l'adapter en 32x32 Je suis d'accord, elles sont vraiment belles et ce site est une petite perle pour trouver de l'inspiration.

Masséna a écrit :
Tu comptes mettre quoi dans la section du dessous ?

Pour le moment je n'ai pas prévu de la remplir. En fait initialement je ne voulais pas avoir de fond gris pour laisser le jeu en arrière plan, mais à cause de certaines actions avec les items (boite de dialogue, contexte dans lequel l'inventaire est ouvert), il y avait parfois des résidus vraiment pas agréables

À terme je pense que je ne vais pas avoir assez de place pour la description complète des items, il se pourrait que je profite de l'espace du bas pour étendre la description. Il y a également certaines actions possibles dans l'inventaire comme activer la suppression ou (peut-être) le trier. Je peux également utiliser cet espace libre pour ajouter les boutons et leurs actions respectives.

Lephé a écrit :
La ligne parallèle tout en bas à droite contribue beaucoup à la structure à mon avis, mais il m'a fallu longtemps pour la voir. Il y a peut-être moyen de la mettre plus en valeur sans grignoter trop d'espace ?

Merci ! J'aime beaucoup rajouter ces petites lignes parallèles dans mes UI, je trouve que ça rajoute un sentiment de "solidité" / de finition dans les interfaces. Je vais essayer de la mettre un peu plus en valeur histoire de mieux la voir.

Concernant le tri, trouvez-vous ça pertinent de l'ajouter ?
Bretagne > Reste du globe
(Et de toute façon, vous pouvez pas dire l'inverse grâce à Bzh)
Projet en cours : Adoranda

Mes programmes
Hésite pas à faire un test !


Lephenixnoir En ligne Administrateur Points: 22261 Défis: 149 Message

Citer : Posté le 31/05/2022 09:35 | #


Le tri je pense que c'est une bonne idée, pas forcément automatique mais au moins avec un bouton.

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2022 | Il y a 46 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd