This commit is contained in:
Kazhnuz 2021-05-08 18:42:49 +02:00
commit e3ebe05dec
202 changed files with 2274 additions and 3307 deletions

View file

@ -6,6 +6,8 @@
"game", "game",
"core", "core",
"scenes", "scenes",
"utils" "utils",
"birb",
"enum"
] ]
} }

View file

@ -1,69 +0,0 @@
# Amy Rose
Plus grande fan autoproclamée de Sonic devenue une ami fidèle du hérisson, Amy Rose est une force de la nature en plus d'être une personne pleine de compassion et d'énergie. Cette jeune hérissonne ne désespère pas de réussir à séduire Sonic, mais est également capable de penser au plus important.
Elle est présente avec Tails et Sonic pour élucidé les mystères de la zone.
## Caractéristiques principales
- Type power
- Agit 2× par tour
- Moins forte que Knuckles, mais plus de technique et quelques capacités de soin
- Peut passer en super state? (j'ai les sprites pour, donc pourquoi pas ?)
### Sur le terrain
> Note : ces capacités de terrain seront pour certaine possible à acquérir et utilisable après l'obtention de certains powerup, à la Sonic Adventure 1 ou 2
- A : Saut
- A+A : Double Saut
- B : Coup de Marteau (permet de détruire des élément du décors)
- CONTEXTUEL : *A trouver*
- PASSIF : *A trouver*
## Système de combat
- **HP** :: Rank A
- **PP** :: Rank C
- **Attack** :: Rank A
- **Defense** :: Rank B
- **Technique** :: Rank C
- **Power** :: Rank B
- **Mind** :: Rank C
- **Speed** :: Rank B
### Techniques
- Rose Heal (soigne un personnage) //A REMPLACER
- Tarot Curse (maudit un ennemi)
- Amy Flash (affecte tout les ennemis avec un effet)
- Piko Tornado (G.Tornado de S. Battle)
- Gift Trap
- Hammer Attack
- Pink Tornado
- Rose Typhon
- Spin Hammer Attack
- Storming Heart (comme le Amy Flash, mais sur un ennemi + quelques dégats)

View file

@ -1,71 +0,0 @@
# Cream the Rabbit
Cream est la fille de Vanilla the Rabbit, une petite lapine calme et polie qui n'aime pas se battre. Cependant courageuse, elle n'hésite pas à venir à ses ennemis en aide. Ce n'est pas le danger qui lui fait peur, mais le fait de ne pas aimer la violence.
Elle rejoindra l'équipe après avoir été lors d'une quête annexe.
*TODO:* Déterminer la raison de sa présence.
## Caractéristiques principales
- Type Technique
- Agit 2× par tour
- La plus faible en force et en pouvoir, Cream est cependant la meilleurs healeuse du jeu.
- Ne peut pas passer en super state.
### Sur le terrain
> Note : ces capacités de terrain seront pour certaine possible à acquérir et utilisable après l'obtention de certains powerup, à la Sonic Adventure 1 ou 2
- A : Saut
- A+A : Vole
- B : Chao Dash (permet de toucher des éléments à distance)
- CONTEXTUEL : *À trouver*
- PASSIF : *À trouver*
## Système de combat
- **HP** :: Rank A
- **PP** :: Rank B
- **Attack** :: Rank D
- **Defense** :: Rank B
- **Technique** :: Rank A
- **Power** :: Rank C
- **Mind** :: Rank A
- **Speed** :: Rank C
### Techniques
- Chao Attack
- Heal Cheer
- Revive Cheer
- Thoughness Cheer
- Refresh Cheer
- Cure Cheer
- Demoralize
- Omochao Trap
- Chao Tornado (Chao Rush de S. Battle)
- Chao Canon

View file

@ -1,70 +0,0 @@
# Espio the Hedgehog
Ninja des Chaotix, Espio est sérieux et concentré, et se laisse peu distraire par le divertissement et autres choses du genre.
Il est présent pour enquêter sur la société Rimlight, et sur ses rapports avec GUN. Il s'intéressera particulièrement à l'affaire de la Gosth Central.
## Caractéristiques principales
- Type Speed
- Agit 2× par tour
- A pas mal de capacité pour esquiver. Basé pas mal sur les critiques.
- Ne peut pas passer en super state.
### Sur le terrain
> Note : ces capacités de terrain seront pour certaine possible à acquérir et utilisable après l'obtention de certains powerup, à la Sonic Adventure 1 ou 2
- A : Saut
- A+A : Jump Dash (+ Homming Dash si powerup)
- B : Kunai, touche à distance
- CONTEXTUEL : *À trouver*
- PASSIF : *À trouver*
## Système de combat
- **HP** :: Rank B
- **PP** :: Rank C
- **Attack** :: Rank A
- **Defense** :: Rank C
- **Technique** :: Rank B
- **Power** :: Rank C
- **Mind** :: Rank A
- **Speed** :: Rank A
### Techniques
- Shuriken
- Expl. Kunai
- Chroma Camo (augmente esquive pd 3 tours, passe Espio dans son set de Sprite "invisible")
- Leaf Swirl (tornade qui touche tout les ennemis autour et rend espio invisible 1 tour)
- Chaotic Tornado (Espio tournoi et provoque des dégats tout autour)
- Ninja Trap (Espio fait apparaitre un explosif dans le sol)
- Tornado Dash (Espio tournoi et attaque en avant sur qq cases)
- Poison Kunai
- Ninja Trick (produit un effet faibless aux ennemis autour)
- Ninja Focus (le personnage reçoit le status "FOCUS")

View file

@ -1,75 +0,0 @@
# Knuckles the Echidna
Knuckles est le gardien de la Master Emerald, ayant vécu en ermite depuis toujours sur Angel Island, l'ile flottante où la gemme mystique repose. Cet echidné prend son rôle au sérieux, et ne supporte pas que quiconque pose la main dessus. Dupé mainte fois par le passé, il est désormais plus prudent.
*TODO:* Déterminer la raison de sa présence.
## Caractéristiques principales
- Type power
- Agit 2× par tour
- Personnage le plus fort, assez tanky, mais peu resistant sur le mental
- Peut passer en super state
### Sur le terrain
> Note : ces capacités de terrain seront pour certaine possible à acquérir et utilisable après l'obtention de certains powerup, à la Sonic Adventure 1 ou 2
- A : Saut
- A+A : Plane
- B : Coup de Poing (permet de détruire des élément du décors)
- CONTEXTUEL : Creuse
- PASSIF : Détecteur de trésor.
## Système de combat
- **HP** :: Rank A
- **PP** :: Rank D
- **Attack** :: Rank S
- **Defense** :: Rank A
- **Technique** :: Rank C
- **Power** :: Rank C
- **Mind** :: Rank D
- **Speed** :: Rank C
### Techniques
- Spin Attack
- Spin Dash
- Deep Impact
- Spin Drill
- Enrage
- Ground Shaker / Hammer Punch (touche tout les ennemis sur une grande zone, utilise le Knux. Chop comme sprite)
- Uppercut
- Maximum Heat Knuckles
- Mole Bomb
- Meteor Crush
- Thunder Arrown
- Volcanic Dunk
- Guardian Heal

View file

@ -1,73 +0,0 @@
# Miles "Tails" Prower
Le renardeau suivant Sonic depuis (presque) toujours. Inventif et intelligent, Tails n'est pas autant un combattant que ses amis mais à appris à se débrouiller en combat. Il souffre d'un manque de confiance en lui, qu'il a commencé à apprendre à dépasser, mais Rome ne s'est pas faite en un jour.
## Caractéristiques principales
- Type Technique
- Agit 2× par tour
- Est le deuxième plus faible des perso principaux, mais peut faire pas mal d'effets secondaire et est bon avec les objets. Personnage équilibré de soutiens.
- Peut passer en super state.
### Sur le terrain
> Note : ces capacités de terrain seront pour certaine possible à acquérir et utilisable après l'obtention de certains powerup, à la Sonic Adventure 1 ou 2
- A : Saut
- A+A : Vole
- B : Arm Canon (permet de toucher des éléments à distance)
- CONTEXTUEL : Interragit avec les machine.
- PASSIF : *À trouver*
## Système de combat
- **HP** :: Rank C
- **PP** :: Rank A
- **Attack** :: Rank D
- **Defense** :: Rank C
- **Technique** :: Rank S
- **Power** :: Rank C
- **Mind** :: Rank A
- **Speed** :: Rank B
### Techniques
- Spin Attack :: une course tourbillonante attaquant un ennemi au sol sur trois case devant le personnage.
- Spin Dash :: une course tourbillonante chargée attaquant un ennemi au sol sur cinq case devant le personnage. Le personnage se défend automatiquement pendant le tour de charge et inflige des dégats sur les techniques direct.
- Adrénaline Rush :: Le personnage peut activer un mode Hyper sur un personnage au choix.
- Chu² Bomb :: Un piège qui traverse le terrain jusqu'à un ennemi (1 case/tour)
- Dummy Ring Bomb :: Lance trois anneau paralysant devant le personnage.
- Energy Shot :: Attaque à distance paralysante sur un ennemi en avant (5 case)
- Mecha Hook :: Lance un coup de poing mécanique tout autour de lui. Peut étourdir
- Magic Upper :: Lance un coup de poing concentré puissant sur une case devant lui.
- Tail Attack :: Un coup de queue qui attaque sur trois case devant le héros.
- Rapid Tail Attack :: Un coup de queue tournoyant attanquant tout autour plusieurs fois.
- Scan :: Permet d'obtenir les informations sur un ennemi
- Energy Laser :: Tir perforant touchant tous les ennemis en avant.
- Ajouter un Heal

View file

@ -1,75 +0,0 @@
# Rouge the Bat
Espionne du gouvernement, intelligente, voleuse et aimant bien se jouer des autres. Aimant particulièrement taquiner Knuckles et tenter de lui voler la master emerald - bien qu'on peut se demander si le fait que ça énerve l'échidné n'est pas en soi une raison suffisante.
Elle est présente dans la base pour faire des recherche sur le projet Gosth Central et la manière dont Eggman à obtenu des informations dessus. Elle rejoindra l'équipe avec des informations sur le projet Gosth Central, et sur le rôle de Rimlight dans toute cette histoire.
## Caractéristiques principales
- Type technique
- Agit 2× par tour
- Personnage technique assez puissant en combat, avec pas mal de capacité pour mettre des altération d'état
- Ne peut pas passer en super state
### Sur le terrain
> Note : ces capacités de terrain seront pour certaine possible à acquérir et utilisable après l'obtention de certains powerup, à la Sonic Adventure 1 ou 2
- A : Saut (avec chute ralenti à la Battle ?)
- A+A : Vole
- B : Coup de pied (détruit objet fragile + plus solide si powerup)
- CONTEXTUEL : peut creuser.
- PASSIF : Détecteur de trésor.
## Système de combat
- **HP** :: Rank C
- **PP** :: Rank A
- **Attack** :: Rank D
- **Defense** :: Rank C
- **Technique** :: Rank A
- **Power** :: Rank B
- **Mind** :: Rank C
- **Speed** :: Rank D
### Techniques
- Spin Drill
- Upper Attack (Secret Kick)
- Black Wave
- Bat Kick
- Bat Bomb
- Beauty Choc
- Charly Kick (coup de pied qui attaque tout autour)
- Distract (Generation / Chronicles)
- Jewel Storm ?
- Shriek
- Plunder
- Silent Size
- Attaque à la "vampirisme" de pokémon.

View file

@ -1,75 +0,0 @@
# Shadow the Hedgehog
L'espèce vivante suprême, un hérisson sombre et peu loquace. Rarement la personne la plus sympathique avec qui parler, parfois trop sûr de sa propre puissance, et plus souvent concentré sur sa mission que sur aider chaque personnage sur son passage, Shadow n'en est pas moins quelqu'un de dévoué pour protéger la planète.
Il est ici afin de découvrir qui est le mystérieux "traitre" qu'il y aurait dans l'administration de la zone.
## Caractéristiques principales
- Type Speed
- Agit 3× par tour
- Personnage le plus puissant à distance, et bon en vitesse. Peu de PV et
- Peut passer en super state
### Sur le terrain
> Note : ces capacités de terrain seront pour certaine possible à acquérir et utilisable après l'obtention de certains powerup, à la Sonic Adventure 1 ou 2
- A : Saut
- A+A : Jump Dash (+ Homming Dash si powerup)
- B : Course (permet d'aller plus vite, et de passer certains obstacle)
- B au bout d'un moment : Dash mode, permet de courir sur l'eau notamment (si powerup)
- CONTEXTUEL : Light Dash
- PASSIF : *À trouver*
## Système de combat
- **HP** :: Rank D
- **PP** :: Rank B
- **Attack** :: Rank A
- **Defense** :: Rank D
- **Technique** :: Rank C
- **Power** :: Rank S
- **Mind** :: Rank D
- **Speed** :: Rank A
### Techniques
- Spin Attack
- Spin Dash
- Chaos Boost (boost temporairement ses stats)
- Chaos Control (comme le Time Stop en plus puissant)
- Chaos Blast (dégats à tout les ennemis)
- Chaos Burst (attaque autour)
- Chaos Rift (fusion avec Chaos Magic de Sonic Battle)
- Chaos Nightmare/Sphere (affect les deux côtés, ralenti les ennemis)
- Chaos Spear (attaque droit devent, perce les armures)
- Maria's Wish (regénération)
- Chaos Lance
- Light Speed Attack

View file

@ -1,9 +0,0 @@
# Sonic Radiance - Personnages liés à GUN ou aux FUs
> TODO: Update to the new concepts
- **Ys Gradlon** est l'ancien commander des armées du GUN, disparu il y a de cela 12 ans lors de l'incident de Gosth Island.
## Les Chaos Breakers
> Les Chaos Breaker sont un groupe para-militaire venant essentiellement de GUN, qui sont particulièrement inquiet à cause des pouvoirs développés par les hybrides. Ils ont peur que cette différence de puissance fasse tomber leur peuple en position de faiblesse.

View file

@ -1,51 +0,0 @@
# Sonic Radiance - Direction et Management de Monado Prime
> TODO: Update to the new concepts
## Gabriel Seraph (directeur de Monado Prime)
- **Espèce :** Humain
- **Age :** 52 ans.
- **Description Physique :** Gabriel Seraph est un grand homme, qui peut parraitre aux premiers abords imposant. Il porte constamment un costume avec son insigne de commandement de Monado One. Il porte de petite lunette rectangulaire, et ses cheveux grisonnant sont rabattu en arrière.
- **Histoire et description psychologique :** Gabriel Seraph est le nouveau chef de la base depuis l'incident d'il y a 12 ans, avant quoi il était le second d'Ys Gradlon dans la direction de la base. Si son élection a été unanime, il est souvent vu comme un couard imbécile et inepte, incapable d'arriver à la cheville de son prédécesseur. Il est mal vu à cause de principalement deux évévenements : son incapacité à dire ce qui s'était exactement passé lors de l'incident qui a tué Ys Gradlon ainsi que de nombreux ingénieurs, et le fait d'avoir accepté l'offre de HexaECO (compagnie rivale d'énerige de Rimlight) pour obtenir de l'énergie dans la base.
Celui-ci accorde cependant peu d'importance à son image, estimant que "tout l'honneur de ce cher conseil d'administration n'aurait qu'affamé la base". Il n'hésitera pas cependant à critiquer publiquement ses adversaires sur leurs affirmations, rappellant que les centrales chaotiques ne permettent pas la construction d'une nouvelle après incident.. Cela lui permettra de perdre une partie de ses adversaires, lui assurant peu d'ennemis dans son propre camp pendant les les premières année de son mandat.
Cependant, il recommence à être raillé depuis l'arrivée de badnics du Dr. Robotnik, pour son incapacité à agir. L'appel de Sonic, Tails et Amy sera la culmination de cela, et aujourd'hui son mandat est très mal vu par ses adversaires, qui appellent à sa démission.
### Belissama (dirigeante de la phytosphère)
- **Espèce :** Chèvre
- **Age :** 34 ans
- **Description Physique :** Belissama est une grande mobienne, avec une forte carrure. Son pelage est du même blanc neige teinté de marron que ses deux enfants, mais avec deux immenses cornes partant sur les côtés. Belissama porte généralement un uniforme de la base, faisant partie de la classe dirigeante
- **Histoire et description psychologique :** Fille de l'ancienne Grande Prêtresse du peuple Sidh *Morrigan*, et mère de Taranis et Anrad, Belissama est une femme rude et autoritaire, qui s'occupe du bon fonctionnement politique de la phytosphère, et notamment des nombreux anciens membres du peuple Sidh qui s'y trouve. Elle était destinée à devenir la nouvelle Grande Prêtresse, mais a dû reprendre le rôle de son père depuis la mort de son frère, son époux et ses deux parents lors de l'incident d'il y a douze ans.
Devant à la fois s'occuper de ses enfants et d'un village entier, tout en faisant le deuil de tout ses proches, Belissama a décidé à ce moment au grand déplaisir des autres anciens membres du peuple Sidh de ne pas reprendre aussi le rôle de prêtresse, estimant que la vie de son peuple et de sa famille était plus important que les légendes de son peuple. Cependant, elle laissa à Anrad la possibilité d'apprendre sur le rôle de prétresse quand celle-ci affirma son intérêt pour. Elle déclare aujourd'hui toujours que même si prendre le rôle de prêtresse aurait sans doute permis d'aider face à la *maladie*, tout est mieux que si elle avait tenté de tout faire à la fois.
Son mandat ne fut pas facile, puisqu'elle du faire avec les critiques sur le fait qu'elle n'avait pas accordé plus d'attention à son rôle de prêtresse, les doutes sur sa capacité à diriger en ayant des enfants aussi indiscipliné que les siens, l'apprentissage de sa fille, le manque d'intérêt politique pour la vie des anciens du peuple Sidh et la préservation de leur tradition, ainsi que la haine latente entre ceux qui avaient accepter la construction de Monado Prime et ceux qui l'avaient refusé. Elle a entraîné également au combat son fils, étant elle-même capable de se défendre en combat singulier.
Cependant, les choses ont changés aujourd'hui et nombreux sont aujourd'hui ceux qui la respecte pour sa force, son courage ainsi que son écoute envers les scientifique et son équipe. Sa force de caractère et son esprit combatifs lui permirent non seulement de résister à la charge de travail, mais également aux tentatives d'influence et d'intimidation de Robotnik.
Elle fut très déçu quand elle appris que son fils avait travaillé pour Eggman, bien plus qu'en colère.
### Lug (dirigeant de l'hydrosphère)
- **Espèce :** Taureau
- **Age :** 65 ans
- **Description Physique :** Lug est un immense taureau, imposant et charismatique. Sa fourrure est entièrement noire, et il porte fièrement l'uniforme de Monado Prime.
- **Histoire et description psychologique :** Lug est le plus ancien des dirigeant de Monado Prime, et également celui qui a signé le contrat de collaboration entre le Peuple Sidh et le projet Monado il y a plus de 30 ans. Il estime que cette collaboration est importante pour les deux partie, et que le Stygian Rift aurait été plus utile mieux exploité que laissé à l'abandon. Il est l'un des dernier des 12 chefs encore en vie.
Si pas mal de membre du peuple Sidh le voit comme un vénal qui a vendu son peuple pour sa petite vie paisible, il prend très à cœur les conditions de vie de son peuple. Il négocie constamment pour laisser une plus grande place aux traditions du peuple Sidh dans la vie de la base, et lutte activement contre les différence salariale et de niveaux de vies entre les différentes couches sociales de la base.
Malgré les rumeurs, il n'y a pas d'animosité entre lui et Belissama, et les deux réussissent à travailler ensemble sans trop de problème.
Plus accessible et moins "effrayant" que Belissama, il aidera autant que possible les héros dans leur quête contre le Dr. Robotnik.

View file

@ -1,17 +0,0 @@
# Sonic Radiance - Membres du peuple Sidh
> TODO: Update to the new concepts
## Morrigan
L'ancienne prétresse du Stygian Rift et la grand-mère de Taranis et Anrad. Sorcière puissante et presque légendaire, elle est encore admiré voir crainte malgré sa mort il y a 12 ans lors de l'incident. Ses pouvoirs était tout autant connu que son caractère droit et puissant. On dit qu'elle était même crainte de Bénélos.
## Benelos
L'un des douze chef d'avant la grande lutte. Cet immense et ancien Bison était un guerrier fier et féroce, qui dès que le projet de la Gosth Central à commencé à avoir des problèmes, s'est farouchement opposé à Ys Gradlon. Cependant, si ces instincts guerriers était pour protéger son peuple, c'est lui qui a prononcé le banissement de tout ceux ayant aidé le projet de centrale, et qui a lancé la bataille finale ayant provoqué l'embalement des problèmes.
Il est vu au village principal comme un grand héros, et tout ceux remettant en doute ses agissements sont généralement mal vu.
## Dahut
Une brebis, mère d'Ankou et ancienne scientifique ayant travaillé sur le projet Millenium. Docteure en énergie chaotique optimiste sur le fait que les sciences aideraient le monde à devenir meilleur, elle a participé au projet dès qu'elle à sû que le conglomérat était intéressé par le Stygian Rift. Elle est celle qui a convaincu une partie des douze chef d'accepter le projet. Elle est morte lors de l'incident. À cause de cela, elle est considérée comme coupable de toute ce qui s'est passé durant ce projet, et son fils unique Ankou subit les contrecoups de cette réputation.

View file

@ -1,51 +0,0 @@
# Sonic Radiance - Personnages jeunes et adolescents
> TODO: Update to the new concepts
## Taranis
- **Espèce :** Bouc
- **Age :** 14 ans.
- **Description Physique :** Taranis est un jeune bouc blanc, dôté de gants et chaussure style "cuir"/"aventurier". Il porte toujours une sorte de bateau d'acier, où il peut faire transiter de l'électricité.
- **Histoire et description psychologique :** Taranis est l'un des descendant du peuple Sidh de la base. Vivant dans une cabane située dans les bois de la pythosphère, c'est un adolescent colérique, plein de rage contre les injustices qui existent dans la base. Il faut dire, sa mère était fille d'un des 12 chefs du peuple Sidh, et est l'une des dernière personne qui tente tant bien que mal de maintenir une forme d'équilibre chez les descendants du peuple Sidh dans la base.
Il travaille secrètement pour l'Eggman Empire, ayant été amené par Eggman suite à diverse action positive que celui-ci à fait pour quelques membres du peuples sidh, tel qu'attaquer des créantiers, où protéger secrètement une de leur cachette dans la phytosphère. Il n'est pas vraiment au courant des plans du docteur, mais veut lui payer sa dette, et n'a pas grand chose à faire des conséquences des actions d'Eggman pour le reste des Fédérations Unis où pour la ville principale.
Taranis à de ce fait une vision assez sombre du monde, furieux de l'injustice qu'à subit son peuple, et de l'expropriation de leur propre territoire. Pour lui, tout cela est de la faute des constructeurs de la base. Il a une animosité pour toute personne travaillant pour le projet, jeune ou adulte, et surtout pour Ankou, dont la mère s'occupait du design de la Gosth Central. Cependant, il fait partie des rares personnes ne pensant pas qu'Ankou est un poison *en lui-même*. Il est juste pour lui le fils d'une traitresse au peuple Sidh.
Il a énormément de mal à faire confiance aux autres, mais à une certaine attirance qu'il essaie de combattre pour les idéaux de Sonic. Est-il bien possible de sauver tout le monde, existe-t-il une solution pour aider son peuple sans faire de mal à qui que ce soit ? Il aimerait y croire, mais n'y arrive pas.
## Ankou
- **Espèce :** Mouton
- **Age :** 13 ans.
- **Description Physique :** Un petit mouton noir un peu chétif, le jeune Ankou se remarque surtout par son grand médaillon, et la grande cape qui l'entoure entièrement, comme pour le protéger. Il a de toute petite corne qui dépassent à peine du sommet de son crane.
- **Histoire et description psychologique :** Craintif, peu loquace et encore moins accessible, Ankou est un jeune orphelin qui se cache une grande partie du temps dans les zones inutilisée où "technique" de la base. Il connait tout les passages secrets de Monado Prime et les utilise pour s'éloigner des autres. Il a d'ailleurs dans un mur de la base l'endroit où il vit, une sorte de zone de passage de tuyant avec dedans un hamac volé et de quelques magazines récupéré à droite à gauche.
Ankou est comme il est à cause des brimades et du harcèlement qu'il a subit de ses camarades depuis qu'il est tout jeune. Il est le fils de Dahut, l'ingénieure de la Gosth Central, et si peu de gens connaissent exactement ce qu'elle était, ils le voit comme le fils de la cause de l'incident d'il y a 12 ans. Certains, moins au fait, croient qu'il est la cause du "poison", un mystérieux phénomène ayant conduit à la fermeture de plusieurs endroits. Surnommé carrément "le Poison", il a donc constamment été rejeté.
Très défaitiste et avec une grande tendance à se déprécier (voir à se haïr), Ankou estime qu'il ne mérite pas spécialement d'être "sauvé". Il a constamment l'impression que vu son ascendance, il devrait plus "laisser les autres tranquille" et vivre dans son coin. Il a du mal à accepter les preuves d'amitié. Il n'essaie à cause de cela même pas de se défendre, et se laisse tristement faire quand on l'attaque. Ankou est non-combattant, et n'aime pas du tout l'utilisation de la force.
Anrad est l'une des rares personnes à faire preuve de gentillesse avec lui, et paradoxalement il trouve Taranis moins pire que les autres, parce que même s'il sait parfaitement que le jeune Bouc le hait, le bouc n'irait jamais s'attaquer à plus faible, et ne le considère pas comme la source du poison. Cependant, Taranis n'est pas tendre non plus, et rejète constamment Ankou quand il tente de l'approcher.
## Anrad
- **Espèce :** Chèvre
- **Age :** 16 ans.
- **Description Physique :** Une chèvre plutôt de grande taille, avec des cornes imposante, et une grande tenue de barde. (Grand chapeau, vêtements type "voyageur ancien").
- **Histoire et description psychologique :** Anrad est une jeune barde, qui fait souvent tâche dans la station. Beaucoup de gens la trouve bizarre, voir effrayante, ce malgré un caractère plutôt jovial et accessible. C'est que, dénuée de toute honte de ce qu'elle est, d'envie de correspondre aux normes sociales ou de discretion, la chèvre n'hésite pas du tout à aller voir les passant pour leur raconter les chants anciens du peuple Sidh, où à faire des grands discours sur la place public.
Les forces de l'ordre elles-mêmes souvent hésitent un peu à la déloger, de peur qu'elle aurait quelques pouvoirs mystiques Sidh caché, surtout que malgré qu'elle fasse un peu flipper, elle est plutôt appréciée des gens. Si les rumeurs disent que ses pouvoirs sont formidable, elle ne semble pas se battre. Elle a également une formidable tendance à troller, étant très forte pour remarquer les paradoxes chez les autres comme chez elle-même.
Après, ses actions ne sont pas que de l'excentrisme. Bien plus sage et réfléchie que son frère, et même que le jeune Ankou, elle est gardienne des anciens chants de la civilisation Sidh. Elle a refusée daider Eggman dans sa quête, mais d'un autre côté n'a rien révélé du rôle de son frère dans les plans d'Eggman aux autorités. Elle forme une sorte de troisième camps entre Eggman et la direction de Monado Prime. Elle suivra les héros plusieurs fois, intéressée par leurs objectif, et voulant sauver son frère des griffes d'Eggman.
Elle s'en veut secrêtement de son échec à avoir gardé son frère dans la lumière.

View file

@ -1,75 +0,0 @@
# Sonic the Hedgehog
Le hérisson le plus rapide du monde est de retour ! Orgueilleux, fier et inarrêtable, Sonic est toujours l'amoureux de la liberté et de la course qu'il a toujours été. Étonnamment plus malin qu'il le laisse paraître, le hérisson a été appellé par le dirigeant de la zone avec Tails et Amy afin d'aider face à une invasion de Badniks.
Toujours heureux de pouvoir aider les gens, il n'a pas hésité et le voilà à présent pour convattre Egman.
## Caractéristiques principales
- Type Speed
- Agit 3× par tour
- Est pas extrèmement fort mais rapide et avec une bonne précision
- Peut passer en super state.
### Sur le terrain
> Note : ces capacités de terrain seront pour certaine possible à acquérir et utilisable après l'obtention de certains powerup, à la Sonic Adventure 1 ou 2
- A : Saut
- A+A : Jump Dash (+ Homming Dash si powerup)
- B : Course (permet d'aller plus vite, et de passer certains obstacle)
- B au bout d'un moment : Dash mode, permet de courir sur l'eau notamment (si powerup)
- CONTEXTUEL : Light Dash
- PASSIF : *À trouver*
## Système de combat
- **HP** :: Rank B
- **PP** :: Rank C
- **Attack** :: Rank B
- **Defense** :: Rank B
- **Technique** :: Rank C
- **Power** :: Rank C
- **Mind** :: Rank D
- **Speed** :: Rank S
### Techniques
- Spin Attack :: une course tourbillonante attaquant un ennemi au sol sur trois case devant le personnage.
- Spin Dash :: une course tourbillonante chargée attaquant un ennemi au sol sur cinq case devant le personnage. Le personnage se défend automatiquement pendant le tour de charge et inflige des dégats sur les techniques direct.
- Homming Attack :: Le personnage peut viser un ennemi autour de lui sur un rayon de deux case, le frappant automatiquement. Touche les ennemis aérien. Avec les niveaux, ils peut viser plus d'ennemi.
- Light Speed Attack :: Technique ultime Speed - homming attack sur tous les ennemis du terrain.
- Boost :: Le personnage attaque un ennemi sur cinq case devant lui, traverse les ennemis.
- Blue Tornado :: Le personnage balance une tornade attaquant sur un carée de 3×3 case devant lui. Les ennemis au centre se prennent plus de dégats. Supprime les bouclier.
- Sonic Wind :: Brise les bouclier de tous les ennemis devant le personnage.
- Sonic Cracker (piège) : Le personnage pose un piège qui explose au contact d'un ennemi.
- Sonic Flare : Le personnage attaque tous les ennemis autour de lui, attaque lourde.
- Sonic Wave : Le personnage envoie une vague d'énergie devant lui. Peut étourdir les ennemis.
- Speed Up : Le personnage produit l'effet "Speed Up" à un personnage au choix, lui apportant une attaque supplémentaire.
- Time Stop : Le personnage produit l'effet "figé" à un ennemi pendant 1 tours.

View file

@ -1,66 +0,0 @@
# Sonic Radiance - Item List
## Healing items
### HP-healing items
- Chili Dog (10)
- Egg Dog (-1)
- Health Seed (50)
- Health Leaf (100)
- Health Root (250)
- Health Fruit (100%)
- Health Emmitter (30, 5 turns)
- Health Wave (100, everybody)
- Revival Gem (Revive, HP=10%)
- Life Gem (Revive, HP=100%)
- Divine Gem (Revive whole team with 100% HP)
### PP Healing items
- Tonic Drink (10)
- Tonic Infusion (20)
- Tonic Potion (50)
- Tonus Emmitter (6, 5 turns)
- Refresher Wave (20, everybody)
### Status healing
- Antidote (cure poison)
- Strenth Restorer (cure weakened)
- Defense Restorer (cure vulnerable)
- Movement Restorer (cure paralysis)
- Awakener (cure sleep)
- Cure-All Spray (cure all status)
- Heal Unit (cure all status + restore all HP)
## Battle items
### Powerups
- Power Ring (give "Hyper" 5 turns)
- Psychic Water (give "Hidden" 5 turns)
- Focus Rock (give "Focus" 5 turns)
- Clover Juice (give "Lucky" 5 turns)
- Immunity Booster (avoid bad status during 5 turns)
- Shield (give "Fortified" 5 turns)
- Water Shield (protect from Water 3 turns)
- Fire Shield (protect from Fire 3 turns)
- Thunder Shield (protect from Thunder 3 turns)
- Gold Shield (Fortified + Re-heal PP & MP 3 turns)
- Invincibility (give "Invincible" pendant un turns)
- Speed Up (give "Speedup" pendant deux turns)
### Wisps
- Red Wisp : Burst - All target - 120 - No effect
- Orange Wisp : Rocket - 1 target - 150 - Weakened
- Yellow Wisp : Drill - 1 target - 150 - Vulnerable
- Cyan Wisp : Laser - 1 target - 150 - Paralyse
- Violet Wisp : Void - All target - 80 - Sleep

View file

@ -1,19 +0,0 @@
## Elements
Like Sonic Chronicles, Radiance will use a slight Element system, in order to add strenths and weaknesses to ennemies and characters.
The six elements are :
- Water : Aquatic badnics
- Fire : Fire-using badnics
- Ice : Snow level badnics
- Wind : Aerial badnics
- Earth : underground badnics
- Light(ning) : Electricity-using badnics.
A seventh is the chaos, that is weak to itself. It's the element of Phi-based bots, Android Shadows, etc.
Each elements is weak to the previous on the list (Water -> Fire -> Ice -> Wind -> Earth -> Light), and resists to itself and to the next.
Each heroes will have one elemental weakness and one resistence.
Each badnics will have an element, and will follow the normal circle.

View file

@ -1,83 +0,0 @@
# Sonic Radiance - E-00 : Classic Badniks
**Note :** *Ces badnics ne suivent pas exactement la numérotation de Sonic Adventure, même si j'essaie de la reprendre autant que possible.*
- **E-01 Baby Kiki** - Prendre un Kiki de SAdv1 http://sonic.wikia.com/wiki/Kiki
- **E-02 Rhinotank** - Prendre un rhinotank de SAdv1 http://sonic.wikia.com/wiki/Rhinotank
- **E-03 Motobug** - Akatento de SAdv3 http://sonic.wikia.com/wiki/Akatento
- **E-04 Leon** - Leon de SAdv3 - http://sonic.wikia.com/wiki/Leon_(Badnik)
- **E-05 Catterkiller** - Guruguru http://sonic.wikia.com/wiki/Guruguru
- **E-06 Spinner** - Spinner de Colors DS http://sonic.wikia.com/wiki/Bladed_Spinner
- **E-07 IceBot** - Yukigasen de SAdv3 - http://sonic.wikia.com/wiki/Yukigasen - ou Yukimaru - http://sonic.wikia.com/wiki/Yukimaru
- **E-08 Circus Kiki** - Circus Kiki from SAdv2 http://sonic.wikia.com/wiki/Circus
- **E-09 BuzzBomber** - Buzzer recolo de SAdv/SAdv2
- **E-10 Crabmeat** - GamiGami from SAdv - http://sonic.wikia.com/wiki/GamiGami
- **E-11 Bubbles** - Puffer/Senbon from SAdv - http://sonic.wikia.com/wiki/Senbon
- **E-12 BatBot** - Batbot de Colors DS - http://sonic.wikia.com/wiki/Batbot
- **E-13 Turbo Spiker** - Yadokka de SAdv3 - http://sonic.wikia.com/wiki/Yadokka
- **E-14 Flying Motobug** - Aotento de SAdv3 - http://sonic.wikia.com/wiki/Aotento
- **E-15 Orbinaut** - Orbinaut from Sonic Colors DS - http://sonic.wikia.com/wiki/Orbinaut
- **E-16 Electro Spinner** - Electro Spinner from Sonic Colors DS - http://sonic.wikia.com/wiki/Electro_Spinner
- **E-17 Ghora** - Ghora from Sonic Advance 2 - http://sonic.wikia.com/wiki/Gohla
- **E-18 Catterkiller Jr.** - Wamu de Sonic Advance http://sonic.wikia.com/wiki/Wamu
- **E-19 Crabmeat MkII** - https://www.spriters-resource.com/ds_dsi/sonicrushadventure/sheet/20553/
- **E-20 Kiki** - Mon from Sonic Advance 2 - http://sonic.wikia.com/wiki/Mon
- **E-21 Buzzer** :: Buzzer de SAdv3 ou Colors DS
- **E-22 Slicer** - Kamaki de SAdv3 - https://sonic.fandom.com/wiki/Kamaki
- **E-23 Fire Catterkiller** :: Geji-Geji from Sonic Advance 2 - http://sonic.wikia.com/wiki/Geji-Geji
- **E-24 Jetso** - Condor de SAdv3 - http://sonic.wikia.com/wiki/Condor
- **E-25 Flickey** - Flickey de SAdv2 - http://sonic.wikia.com/wiki/Flickey
- **E-26 Bell** - Bell de SAdv2
- **E-27 Grabber** - Kyaccha de SAdv3 - http://sonic.wikia.com/wiki/Kyacchaa
- **E-28 Chopper** - Chopper de Sonic Colors DS
- **E-29 Egg Pirate** - Pirate avec tonneau de SRA https://www.spriters-resource.com/ds_dsi/sonicrushadventure/sheet/20558/
- **E-30 Slot** :: Slot from Sonic Advance
- **E-31 Grounder** :: Mogu from Sonic Advance http://sonic.wikia.com/wiki/Mogu
- **E-32 Unidus** :: Orbinaut recoloré de Colors DS suivant le design Adventure
- **E-33 Jawz** :: Jawz de Colors DS
- **E-34 Plated Spinner** :: Plated Spinner de Colors DS
- **E-35 Mole** :: Mole de Colors DS
- **E-36 Penguinator** :: Pen de Sonic Advance 2 - http://sonic.wikia.com/wiki/Pen
- **E-37 Iceball** - https://www.spriters-resource.com/ds_dsi/sonicrushadventure/sheet/20555/
- **E-38 Bubu** - Bu-bu de SAdv3 http://sonic.wikia.com/wiki/Bu-bu
- **E-39 GaoGao** - (robot lion jouet) - http://sonic.wikia.com/wiki/Gaogao
- **E-99** : Eggrobo

View file

@ -1,15 +0,0 @@
## Série E-100
- **E-100 Zero** (Alpha) - BOSS: le robot qui a poursuivit Amy.
- **E-101 Chaos Beta** - BOSS: Une version reconstruite et améliorée de E-101
- **E-102 Chaos Gamma** - BOSS: Une version reconstruite et améliorée de E-102
- **E-103 Chaos Delta** - BOSS: Une version reconstruite et améliorée de E-103
- **E-104 Chaos Epsilon** - BOSS: Une version reconstruite et améliorée de E-104
- **E-105 Chaos Zeta** - BOSS: Une version reconstruite et améliorée de E-105
- **E-1XX** :: Variante produite en masse de la série E-100, gris. (fusion entre les E-1000 de SA2 et les Guard Robots de Battle)

View file

@ -1,15 +0,0 @@
# Sonic Radiance - E-200 Néo-phi
Des robots basé sur les technologies de Gemerl et des Phi, combinant les capacités de plusieurs personnages en un seul.
- **E-200 Speed Phi** : Un Néo-phi mélangeant quelques capacités de Sonic, Espio et Shadow (bleu).
- **E-201 Brawler Phi** : Un Néo-phi mélangeant quelques capacités de Knuckles, Rouge et Amy (rouge).
- **E-202 Stealth Phi** : Un Néo-phi mélangeant quelques capacités de Rouge et Espio (violet).
- **E-203 Healer Phi** : Un Néo-phi mélangeant quelques capacités de Tails et Cream (blanc).
- **E-204 Trickster Phi** : Un Néo-phi mélangeant quelques capacités de Tails et Rouge.
- **E-205 Power Phi** : Un Néo-phi mélangeant quelques capacités de Shadow et Knuckles.

View file

@ -1,31 +0,0 @@
# Sonic Radiance - Série E-1000+ (Egg Pawn)
- **E-1001 Egg Pawn** - https://www.spriters-resource.com/resources/sheets/10/10012.png
- **E-1002 Egg Flapper** - https://www.spriters-resource.com/resources/sheets/10/10012.png
- **E-1003 Egg Pterodactyl** - https://www.spriters-resource.com/ds_dsi/sonicrushadventure/sheet/20551/
- **E-1004 Kuragen** - https://www.spriters-resource.com/resources/sheets/10/10012.png
- **E-1005 Egg Gosth** - https://www.spriters-resource.com/ds_dsi/sonicrushadventure/sheet/20554/
- **E-1006 Egg Hammer** - https://www.spriters-resource.com/ds_dsi/sonicrush/sheet/20550/
- **E-1007 Shield Pawn** - https://www.spriters-resource.com/fullview/10012/
- **E-1008 Falco** - https://www.spriters-resource.com/resources/sheets/10/10012.png
- **E-1009 Bat Flapper** - https://www.spriters-resource.com/fullview/10012/
- **E-1010 Egg Magician** - https://www.spriters-resource.com/resources/sheets/10/10012.png
- **E-1011 Knight Pawn** - https://www.spriters-resource.com/fullview/10012/
- **E-1012 Rhinoliner** - https://www.spriters-resource.com/ds_dsi/sonicrushadventure/sheet/20551/
- **E-1013 Laser Flapper** - https://www.spriters-resource.com/fullview/10012/
- **E-1014 Electro Kuragen** - https://www.spriters-resource.com/fullview/10012/
- **E-2006 Egg Gunner**

View file

@ -1,13 +0,0 @@
# Sonic Radiance - GUN Ennemies
## Bots
- **GUN Hunter** - https://www.spriters-resource.com/fullview/10012/
- **GUN Hawk** - https://www.spriters-resource.com/fullview/10012/
- **GUN Rhino** - https://www.spriters-resource.com/fullview/10012/
## Soldiers
- **GUN Soldiers** -

View file

@ -1,15 +0,0 @@
# Sonic Radiance - Ennemies
Il va y avoir plusieurs types d'ennemis dans Sonic Radiance : les robots d'Eggman sont les principaux ennemis, mais vous pourrez également affronter des robots du G.U.N. voir d'autres personnages.
## Types d'ennemis dans le dossier :
- *classicbots* : les ennemis "classiques" (basé sur les badnics d'Advance)
- *E-1XX* : Des BOSS/mini-boss basé sur des versions améliorées de la série E-100 apparue dans Sonic Adventure.
- *neophi* : Des nouvelles versions améliorées des Phi, en série E-200. Au lieu de se baser sur un seul personnage, ils en fusionnent plusieurs. Serviront de boss au tout début, puis de mini-boss, deviendront plus fréquent en fin de jeu en tant qu'ennemi normaux.
- *pawn* : Les Egg Pawn, ennemis "normaux" plus puissant que les précédants.
- *gun* : Les ennemis venant du GUN, qui seront utilisé surtout dans certains endroits.

View file

@ -1,76 +0,0 @@
# Sonic Radiance - Gears
Gears are wearable items that enhance characters. Some are specific to some characters, some are available for everybody.
There are three types of characters : Gloves, Shoes and Accessories. Each character can wear one pair of gloves, one pair of shoes, and up to three accessories.
## Shoes
### Boots (Knuckles, Rouge)
- Alloy Boots (Armor +4, Defense +1)
- Light Boots (Armor +1, Defense +1)
- Steel Toe Boots (Armor +3, Power +2)
- Swift Boots (Speed +2, Defense +2)
- Work Boots (Armor +2, Defense +2)
### Sneaker (Sonic, Tails, Shadow)
- Shielded Sneakers (Defense +1)
- Speedy Sneakers (Armor +1, Speed +3)
- Spiked Sneakers (Armor +1, Power +2)
- Stiff Sneakers (Armor +2, Defense +2)
-
### Slippers (Amy, Cream)
- Alloy Slippers (Armor +3, Defense +2)
- Light Slippers (Armor +1, Defense +1)
- Nimble Slippers (Armor +1, Defense +1)
- Spiked Slippers (Armor +1, Power +2)
- Though Slippers (Armor +4, Defense -2)
## Gloves
- Boxing Gloves (Power +1)
- Cloth Gloves (Attack +1)
- Cursed Gloves (Power +6, Attack -2, Defense -2)
- Golden Gloves (Power +1, Attack +2, Defense +2)
- Gritty Gloves (Power +2, Armor +2, Defense -2)
- Lucky Gloves (Attack +1, Luck +2)
- Mirror Gloves (Attack +1, Defense +2)
- Polymer Gloves (Power +1, Armor +1)
- Power Gloves (Power +5, Attack -2)
- Sparkly Gloves (Power +3, Attack -1)
- Work Gloves (Power +1)
## Accessories
### Special Effect
- Angel Amulet (Automatic revive with 1 HP)
- Economizer (All spell -1 PP)
- Immunity Idol (Immunity to negative status effect)
- Refresher (5% PV each turns)
- Replenisher (1PP each turns)
- Spooky Charm (ennemy flee more)
### Dress (Amy, Cream)
- Chao Print Dress (Power +2)
- Pretty Dress (Defense +2, Attack +2)
### Elemental Rings
- Earth Ring
- Ice Ring
- Lightning Ring
- Water Ring
- Wind Ring
### Weapons
- Rock Hammer (Power +10)
- ??? Blade (Attack +4)
- ??? Teleporter (Defense +4)
- ??? Shield (Armor +?)

View file

@ -1,49 +0,0 @@
# Sonic Radiance - Battle System
Le système de combat de Sonic Radiance est un système de combat basée à la fois sur du tactical RPG et sur du JRPG classique. Les personnages et les ennemis sont placé sur une grille de 13×7 case, sur laquelle ils peuvent se déplacer de entre deux et quatre cases par tour.
Les personnages et ennemis agissent plusieurs fois par tour, entre 1 et 3 fois (hors augmentations comme le status *Speed Up*), et agissent à la suite du plus au moins rapide (avec un malus dans les "actions suivantes par tour", ce qui fait que les trois actions de Sonic ne seront pas forcément à la suite, mais cela pourra arriver tout de même face à des ennemis bien plus lent). Les actions sont choisies juste avant le tours (à la Octopath Traveller).
## Compétences utilisables
- **Attaquer** : le personnage fait une série de trois attaques consécutives à 33% de l'attaque. Chaque attaques consécutives peut faire séparément un critique. Certaines capacités passives pourront augmenter le nombre d'attaques pour leur puissance.
- **Compétences** : Le personnage utilise l'une des compétences qui lui est propre. Voir dans les fiches de personnages les compétences utilisables.
- **Objet** : utilisation d'un objet (voir objets)
- **Défendre** : Le personnage se défend, lui permettant d'éviter ce tour-ci les effets d'un piège s'il se retrouve dessus, et d'encaisser une partie des dégats jusqu'à son tour suivant.
- **Fuir** : le personnage tente de fuir.
## Stats
Le système de statistique de Sonic Radiance est le suivant. Les premières states sont les classiques "HP" et "PP", qui représentent respectivement les points dédiés à la vie et aux attaques spéciales
- **HP** :: les points utilisé pour la vie
- **PP** :: les points utilisé pour les POW Moves
À cela se rajoutent 6 autres statistiques :
- **STRENGHT/FORCE** : Affecte les dégats bruts des attaques physiques + skill non-physique en partie
- **DEFENSE** : Affecte la défence face aux attaques physiques + skills non physiques en partie.
- **CHAOS** : Fusionne avec STR et DEF pour affecter l'attaque et resistance aux skills physiques.
- **SPEED/VITESSE** : Affecte l'esquive/precision (légèrement), les chances de fuir et l'ordre dans le tour.
- **TECHNIQUE** : Affecte les dégats des pièges, la réussite des attaques purement status ou dont le status est l'effet principal, la puissance des soins et la puissance des Wisps.
- **LUCK/CHANCE** : Affecte les coup critiques (confrontation des "LUCK"), les chances d'effets secondaire bonus (idem), et peut aider face à certains effets (confusions).
## Apprentissage des attaques.
Les attaques s'apprennent à partir du niveau 5, tout les 4.375 niveau. Une attaque sur trois est un skill passif, avec un total de 6 skills passif et 12 skills actifs à apprendre, jusqu'au niveau 75.
*Apprentissages* : 2 de base + [9, 13, 18, 22, 26, 31, 35, 40, 44, 48, 53, 57, 61, 66, 70, 75]
*Apprentissage des attaques* : [9, 13, 22, 26, 35, 40, 48, 53, 61, 66, 75]
*Apprentissage des passifs* : [18, 31, 44, 57, 70]

View file

@ -1,37 +0,0 @@
## Sonic Radiance - Battle Status
### Positif
- **Camouflé** (Hidden) : Esquive ×1.25
- **Focus** (Focus) : Critical ×1.33
- **Fortifié** (Shielded) : Damage taken ×0.66
- **Hyper** (Hyper) : Damage sent ×1.5, Critical ×1.25.
- **Chanceux** (Lucky) : Enn' critical ×0.66, Side-effect ×0.66.
- **Invincible** : Dégat subit ×0.
- **Acceléré** (Speed'Up) : 1 attaque supplémentaire/tour.
- **Attrap'Anneaux** (Ring) : Ring ×1.5 à la fin du combat
### Négatif
- **KO** (KO) : Ne peut plus agir, 0PV.
- **Empoisonné** (Poison) : -15% PV / tour
- **Affaibli** (Weakened) : Dommage envoyé ×0.66
- **Vulnérable** (Vulnerable) : Dommage subit ×1.33
- **Paralysé** (Paralised) : N'a que 50% de pouvoir agir/se déplacer.
- **Endormi** (Asleep) : Ne peut plus agir ni se déplacer. 30% de chance de se reveiller chaque tour, dure 5 tour max.
- **Maudit** (Cursed) : Crtiques ennemis ×1.33, effet secondaire ×1.33.
- **Distrait** (Distracted) : Précision des attaques ×0.66

View file

@ -1,57 +0,0 @@
# Sonic Boost
## Principe de base
Sonic Boost est un sub-game avec un aspect un peu "mobile" inspiré de plusieurs sources, qui fera partie du projet Sonic Radiance. Ce subgame sera utilise dans le scénario pour des phases "rapides", dans des quêtes annexes comme mini-jeu/mini-niveau, et apparaitra en tant que bonus complet (un peu à la manière du jeu de kart de Sonic Adventure 2)
Ses inspirations sont les suivantes :
- Le premier fangame jamais créé ([Sonic Boom](https://www.youtube.com/watch?v=jYT28un2pEY)), ainsi que son remake ([Neo Sonic Boom](https://www.youtube.com/watch?v=MSofjiB_4J8&t=577s)). Ce jeu se veut sur certain point une combinaison de ce premier fangame avec d'autres sources d'éléments.
- Shadow Shoot, un jeu mobile SEGA du Sonic Café, qui va être la principale source des graphismes et du gameplay de base. Le jeu va reprenddre ses graphismes, et le fait de déplacer sur 5 rails (mais l'aspect "shoot" sera réservé à certains personnages).
- La série de vieux fangame de course "Sonic R GM", "Sonic R DX", "Sonic R MV" de NICKtendo DS
- Les jeux mobile Sonic récent (c'est à dire post-Sonic Café) comme Sonic Dash ou Sonic Runners
- Smash Bros, sur certains points (aspect "collection" et tout)
## Modes de jeux (si c'est possible à mettre dans les temps)
Sonic Boost sera un subgame avec quelques utilisations dans le mode histoire, et quelques modes bonus accessible pour plus de rejouabilité. Les passages en mode "Sonic Boost" seront rejouable dans le menu en plus d'être jouable dans le jeu principal.
### Utilisation dans le mode de jeu principal
Le jeu principal et ses quêtes annexes contiendront plusieurs moments où vous devrez foncer à travers des niveaux en utilisant le gameplay type Boost. Si dans l'aventure principal ils ne seront pas forcément très souvent utilisé (3~4 fois au total), ils seront plus régulièrement présent en tant que niveau bonus permettant d'obtenir des emblèmes supplémentaires, ou en faisant partie de quêtes secondaires.
TODO: Definir exactement quels types de manière dont on peut jouer à un niveau.
Chaque niveau déjà joué sera rejouable dans le menu principal. Ce mode de jeu jeu s'inspirera alors à la fois du mode "Brawl/Smash" de Smash Bros, et de la manière dont se joue les niveaux de Sonic R GM. En effet, vous pourrez choisir votre personnage, puis choisir vos niveaux et la manière dont vous voulez y jouer (mission, mode "rival", etc).
### Mode "Endless"
Ce mode de jeu s'inspire des jeux comme Sonic Runners et Sonic Dash. Vous courrez dans l'un des niveaux disponible, avec des chunks qui se rajouteront au fur et à mesure. Vous avez un temps limité, mais qui se rempli à chaque checkpoint. Ces niveaux devront d'abord être débloqué dans chaque environnement de l'île pour être rejouable dans le menu principal.
Vous n'avez cependant qu'une vie, et le niveau se termine dès que vous perdez.
### Mode Classic
Inspiré du mode classic de Smash Bros, et du premier fangame (Sonic Boom / Neo Sonic Boom).
Vous jouez une série de 7 niveaux, chacun se terminant par un boss. Les niveaux sont choisi de manière semi aléatoire (pour chaque place, il y aura 2 niveaux possible). Dans chaque niveau, vous pouvez trouver une clef, qui vous permettra d'aller dans le special stage ensuite (sauf si vous perdez une vie). Comme dans Smash Ultimate, chaque personnage jouable aura son propre mini "scénario".
Si vous réussissez tout les special stage, vous pouvez aller au dernier niveau spécial "Milky Way".
Certains niveaux auront des gimmicks particulier, basé sur les différentes manières de jouer du mode normal (qui servira aussi à choisir des missions)
### Mode Tournoi
Il sera possible de débloquer quatre "coupe" dans le jeu principal en allant parler à Jet. Chaque coupe terminée pourra être rejouée dans le menu principal.
Cela consistera en un nombre de 4 coupes de 16 niveaux qui seront forcément en mode rival. Il sera possible d'utiliser des Wisps pour déconcentrer les adversaires, avec des effets similaires à ceux du mode combat.
### Mode "Shadow Shoot"
Ce mode de jeu sera aussi utilisé pour créer un clone de Shadow Shoot sur Mobile. Il sera possible de le débloqué après une quête annexe mineure centrée sur Shadow.
NOTE : Cela pourrait simplement être le mode Classic de Shadow ?

View file

@ -1,74 +0,0 @@
## Propositions
### Proposition 1
- **Sunlit Metropolis** (City) : la ville principale de l'ile
- **Radiant Coast** (Plage / Côte) : La zone côtière de l'île, avec les palmier, toussah. C'est ici que se trouve le village "touristique" du peuple Sidh.
- **Ancient Cliff** (Ruines, Falaise) : Les anciennes terres du peuple Sidh, où vivent les Sidh vivant encore conformément aux anciennes règles de leur clan. L'endroit contient de nombreuses ruines Sidh.
- **Lush Forest** (foret/cote) : Les forêt de l'ile *peut-être fusionner cette zone avec Radiant Coast histoire de libérer la place pour un autre truc ?*
- **Utopic Mountain** (grotte, neige, magma, "utopie") : La grande montagne qui surplombe l'ile, et qui donne accès aux anciens espaces d'expérimentation du projet Millenium.
- **Military Bridge** (eau, militaire) : Une grande base de GUN avec des archives sous-marine. Cette base forme un pont sécurisé entre Gosth Island et l'ile principale.
- **Gosth Island/Central** (technologie, ile tropicale) : Une ile entièrement transformée en centrale futuriste. Elle est corrompue par l'énergie du Styx.
### Propositions 2
Le but de cette proposition est d'offrir une plus grande diversité que la proposition 1. En découpant les différents niveaux des Sonic Advance en thématiques, on peut remarquer. En combinant les thémtique du jeu, il serait intéressant d'avoir autant que possible un équilibre entre zones naturelles et artificielles.
- Sunlit Metropolis (ville, route) + funpark et casino en niveau "spécifique".
- Ancien Cliff (ruines, canyon, aride) + halloween en niveau "spécifique". Les anciennes plaines du peuple Sidh. Jadis le cœur de la civilisation, aujourd'hui surtout un endroit sec, aride et où peu pousse.
- Radiant Plains (plaine, foret, jungle) + base, et xxxx en niveau "spécifiques". Les grandes plaines verdoyantes et pleines de beauté de l'île. Surplombant les plages, ces zones
- Shield Coast (plage tropical aquatique) + militaire et "corruption" en niveau "spécifique". De grande plages ainsi que des îlots reposant sur un océan bleuté, qui ont cependant été en première loge lors de l'incident de Gosth Island d'il y a dix ans. Certaines parties sont donc interdites le temps que le nettoyage soit terminé. Quelques espaces sont cependant interdits, controllé par GUN.
- Crystal Mountain (montagne glace grotte) + technologie, base et volcan en niveau "spécifique". La grande montagne surplombant l'île. Contenant de nombreux tunnels, cette montagne offre de nombreux secret à qui s'y aventure. On dit qu'un projet de recherche d'énergie géothermique
- Lost Utopia (technologie base virtuel) + quelques tropes types natures ainsi que virtuel en niveau "spécifique". L'ancienne ville super technologique qui devait être le produit du projet Millenium. Cette base est désormais habité par pas mal de gens cherchant à ne pas être remarqué. Cela peut aller des membres du peuple Sidh voulant être éloigné du tourisme aux membres à notre cher ami le Dr. Robotnik.
- Gosth Island (technologie base militaire) + "out of this dimension" en niveau "spécifique". Une grande île fortifiée, abritant l'ancienne Gosth Central. Fortement gardée par GUN, l'accès à cet endroit est interdit. Vous ne serez pas trop à être nombreux si jamais vous devez y aller…
#### Proposition 2.1
L'idée est de tenter de créer une cohérence entre les niveaux en utilisant une thématique à la Shadow Shoot, les pierres précieuses. Cela participerait à créer une sorte d'aspect "commun" entre les différentes zones de l'île afin de donner l'impression d'un univers "uni". Cela se combine également au fait que Shadow Shoot sera l'une des inspirations du jeu, voir un mini-jeu dedans.
- Sunlit Metropolis -> Diamound Metropolis. Diamound Highway étant le premier niveau de Shadow Shoot, et étant une ville type Station Square de ce que peu en voir conviendrait parfaitement.
- Ancient Cliff -> Moonstone Valley/Cliff. Ce nom rajoute un côté "lunaire" à tout l'espace, ce qui rajoute de l'originalité. Cela fait référence à la fois à la présence de pierre (et fait donc penser aux ruines), à la lune (donc au mystique).
- Radiant Plains -> Jadeite Plains. Ce nom fait référence à la Jadeite Forest de Shadow Shoot
- Shield Coast -> Zircon Coast.
- Crystal Mountain -> Pearl Mountain. Ce nom est directement repris de Shadow Shoot.
- Lost Utopia -> Silicon Utopia. Référence direct à l'aspect hyper technologique de cette Utopie.
- Gosth Island -> Obsidian Island. L'obsidienne est sombre, et y'a souvent l'idée de l'obsidienne comme porte vers d'autres mondes.
#### Proposition 2.2
Cette proposition essaie de prendre comme thématique pour chaque lieu une référence à des concepts moraux et philosophiques, afin de créer une thématique peut-être plus "profonde". L'aventage d'une telle convention de nommage est qu'elle permettrait de créer une cohérence avec un nom de boss final à la "NonAgression" ou "Exception".
- Sunlit Metropolis -> Monado Town/Metropolis/City. *La référence aux monades de leibniz sert à mettre en avant le fait que cette ville est un petit monde à elle toute seule, et jouer sur le fait que la diversité de cette ville en fait d'une certaine manière un "univers".*
- Ancient Cliff -> Faith/Sacred/Holy Canyon/Valley. *Représente les croyances ancestrales du peuple Sidh, et le nombre de ruines ayant un caractère sacré/ou important pour eux. Représente également la vertue theologiale de la foi. D'un point de vue scénario, on pourrait en faire une étape important en étant une foi envers les autres, ce qui pourrait être intéressant pour développer soi Ankou, soit Taranis.*
- Radiant Plains -> Sublime/Aesthetics/Numinous Wilds/Grasses *Ici, le principe est de plus jouer sur l'aspect "esthétiques" des grandes pleines et forets verdoyantes de l'île.*
- Shield Coast -> Paradox/Aphoric Coast. *Une référence directe à sa corruption, ainsi qu'aux paradoxes qui la traverse. D'un côté c'est une belle côte tropicale, de l'autre un espace dangereux corrompu. C'est le lieu des Sidh les plus visible, qui se revandiquent comme porteur de leur culture, mais qui l'ont en partie rendu plus "mercantile". C'est un espace à la fois ouvert sur la plage et sur l'île corrompue. C'est l'océan et l'île. C'est le premier niveau et l'un des derniers. C'est le plus grand lieu accessible au touriste, mais pleins d'interduction soit pour leur sécurité, soit pour les secret de GUN.*
- Crystal Mountain -> Fortitude Mount. *Une montagne est toujours un endroit difficile à traverser, à*
- Lost Utopia -> Utopic Circuits. *Ici, l'idée est juste de créer une cohérence avec les autres, en mettant d'abord en avant l'aspect "utopie". Le but est aussi de bien mettre en avant la croyance en une utopie des gens qui on créé ce lieu, et le fait que leur idée n'étaient pas mauvaise, mais que ça s'est mal passé.*
- Gosth Island -> Wrath Island. *Référence directe aux éléments violents et tragique qui s'y sont passé.*
Boss final : Catharsis/Apathy

View file

@ -1,49 +0,0 @@
# Other RPG
Comment le monde/les régions sont construites dans d'autres RPG, et comment cela pourrait nous aider.
## Légende
- [V+] Ville (importante, avec quelques sous-lieux)
- [V-] Village (juste une petite ville avec qq habitations)
- [B+] Bâtiment de grande taille, presque un petit donjon, ou particulièrement important
- [B-] Bâtiment évenement ou de petite taille
- [D+] Donjon important (type tour pokémon)
- [D-] Donjon mineur (type base de team rocket)
## Pokémon
Pokémon est intéressant, parce que son système de "route" rajoute un aspect presque linéaire qui pourrait bien convenir à l'aspect plateform-y de Radiance. Certaines routes seraient bloqué par le besoin de capacités, ce qui forcerait le joueur à avancer dans le scénario en cas de besoin.
Entre les villes se trouvent également d'autres landmarks "donjon" (genre le Mt Memoria de Hoenn).
Si on prend les différents pokémon de la 3e, 4e et 5e generation, on peut remarquer le nombre de lieux suivants :
### Hoenn
- Routes : 34
- Villes : 16~17
- Lieux importants : 27
### Sinnoh
- Routes : 30
- Villes : 17~18
- Lieux : 45 (compte affecté par le nombre de bâtiment aussi dedans)
### Kanto
- Routes : 25+18
- Villes : 11+7
- Lieux : 17+12

View file

@ -1,165 +0,0 @@
## Prior art
Ici nous allons regardez quelques listes de niveaux de jeux Sonic à sept niveau afin de voir ce qui est possible de faire pour avoir quelque chose d'intéressant.
### Sonic Adventure
- Emerald Coast (plage tropical)
- Windy Valley (canyon ruines)
- Casinopolis (casino)
- Icecap (glace, eau)
- Twinkle Park (fun)
- Speed Highway (ville route)
- Red Mountain (montagne volcan grotte)
- Sky Deck (aerien base eggman)
- Lost World (ruines eau)
- Hot Shelter (aerien base eggman)
- Final Egg (base eggman)
- Sand Hill (desert)
### Sonic Adventure 2
- City Escape / Mission Street (ville)
- Route 101 / Radical Highway / Route 280 (route)
- Wild Canyon / Pumpkin Hill / Sky Rail (canyon halloween)
- Aquatic Mine (eau canyon halloween)
- Dry Lagoon (tropical canyon)
- Weapons Bed / Metal Harbor (base militaire eau)
- Iron Gate / Prison Lane / Security Hall (base militaire)
- Green Forest / White Jungle (jungle)
- Sand Ocean / Hidden / Pyramid Cave / Death Chamber / Egg Quarters (base eggman desert)
- Eternal Engine / Crazy Gadget / Final Rush / Lost Colony / Cosmic Wall / Final Chase (deathegg espace)
- Mad Space / Meteor Herd (espace)
### Sonic Advance
- Neo Green Hill Zone (plage tropical)
- Secret Base Zone (base eggman)
- Casino Paradise Zone (casino)
- Ice Mountain Zone (glace eau montagne)
- Angel Island Zone (ruines canyon)
- Egg Rocket Zone (base aerien eggman)
- Cosmic Angel Zone (base deathegg espace)
### Sonic Advance 2
- Leaf Forest (foret)
- Hot Crater (volcan)
- Music Plant (fun)
- Ice Paradise (glace)
- Sky Canyon (aerien canyon)
- Techno Base (base virtuel)
- Egg Utopia (base deathegg espace)
### Sonic Advance 3
- Route 99 (route ville)
- Sunset Hill (tropical)
- Ocean Base (base militaire eau)
- Toy Kingdom (fun)
- Twinkle Snow (montagne eau glace)
- Cyber Track (virtuel base)
- Chaos Angel (ruines)
### Shadow Shoot
- Diamound Highway (ville)
- Peridot Tunnel (base militaire eau)
- Jadeite Forest (foret)
- Pearl Mountain (montagne glace)
- Calcite Hill (tropical)
- Carnelian Bridge (route)
- Ametist Castle (chateau ruines)
### Sonic Heroes
- Sea Gate / Seaside Hill / Ocean Palace (tropical plage ruines)
- Grand Metropolis / Power Plant (technologie ville)
- Casino Park / BINGO Highway (casino)
- Rail Canyon / Bullet Station (canyon)
- Frog Forest / Lost Jungle (foret jungle tropical)
- Hang Castle / Mystic Mansion (chateau halloween)
- Egg Fleet / Final Fortress (base aerienne eggman)
### Sonic Rush
- Leaf Storm (foret)
- Water Palace (eau ruines)
- Mirage Road (desert base ruines)
- Night Carnival (fun)
- Huge Crisis (base aerienne militaire)
- Altitude Limit (base eau militaire)
- Dead Line (base deathegg espace)
### Sonic Rush Adventure
- Plant Kingdom (jungle plage tropical)
- Machine Labyrinth (base steampunk)
- Coral Cave (grotte crystal eau)
- Haunted Ship (halloween eau)
- Sky Babylon (ruines canyon)
- Blizzard Peaks (glace eau)
- Pirates' Island (eau base)

View file

@ -1,109 +0,0 @@
# Sonic Radiance - Zone
Le jeu entier se passe sur l'ile de Moonstone Island et ses alentours.
Le jeu étant inspiré en grande partie des type Sonic Advance et des jeux mobiles Sonic, le jeu sera comme les Sonic Advance séparé en sept grands environnement. Ces sept zones contiendront les divers lieux important (donjons, ville, etc) - entre deux et trois (ce qui fera entre 14 et 21 "landmarks") - et les routes qui les relient.
Le theme des noms de niveaux essaira d'avoir un theme commun, un peu à la manière de jeux comme Shadow Shoot (ou chaque endroit).
## Notes
- Les Zones (donc les ennvironnement) sont bien plus des "Adventure Field" et des espaces communs, et devront de ce fait être plus généralistes que dans un Sonic habituel (les niveaux genre "la base d'Eggman" ou "Le Casino" seront plus des donjons et des lieux spéciaux plutôt que des zones entières).
- Il faudrait sans doute mieux éviter d'avoir des zones trop "gimmicky" (genre le désert, où la base d'Eggman, qui marche mieux comme un donjon/lieu d'intérêt)
- Note : il y aura quelques donjons et lieux en plus des landmarks (par exemple des bases d'Eggman présente dans les villes)
## Types de lieux
- **Stages** : Ce sont les lieux d'intérêt de chaque zone, représentant des endroits précis, pouvant être comparable à des sortes de donjons (où juste des mini-grottes). Le nombre idéal serait d'en avoir 3~4 par zones, histoire pour chaque zone de pouvoir bien explorer ses possibilités.
- **Routes** : Des endroits séparant deux lieux important. Les routes doivent avoir une composante presque "Action Stage", c'est à dire mettre en avant les capacités des personnages pour avancer, avec presque un peu de "plateforme".
- **Villes** : Le espaces plus tranquilles du jeu, où les personnages peuvent se recharger. Les villes n'ont pas besoin d'être très nombreuses, 1~2 par zones est suffisant.
## Propositions
### Diamound Urbanism
> Le grand espace métropolitain, central de l'île. Cette grande plaine urbanisée abrite la plupars de l'industrie de l'île et les endroits les plus habités.
*(Ville, Technologie, Industrie)*
- **Stages:**
- **Routes:**
- **Villes:** Monado Metropolis, Vanity Streets
### Amber Valley
> Les grandes vallées ancienne de l'île, où se trouve originellement le peuple Sidh. Ses anciens monuments et ruines sont ce qu'il reste de la grande époque de la civilisation. Des micro-climats arides peuvent s'y trouver.
*(Aride, Canyon, Ruines)*
- **Stages:**
- **Routes:**
- **Villes:** Faith Citadell, Righteous Monastery,
### Calcite Plains
> Les plaines verdoyantes de l'île. Cet espace est le second plus peuplé de l'île, avec quelques villages assez important.
*(Plaines, nature, collines)*
- **Stages:**
- **Routes:**
- **Villes:** Modesty Town
### Sapphire Ocean
> Les côtes et l'océan de l'île. C'est ici que se trouvent notamment de nombreuse bases militaires de GUN, qui protège l'île d'Obsidian Island
*(Plages, Ocean, + un peu de Militaire, Ponts)*
- **Stages:**
- **Routes:**
- **Villes:** Aphoric Base, Prodigality Port
### Pearl Mountains
> Les grandes montagnes glacée de l'ile. Les restes du projet Silicon Utopia se trouvent cachée dans ces grands monts glacés.
*(Glace, Neige, Montagne)*
- **Stages:**
- **Routes:**
- **Villes:** Fortitude Village, Utopic Circuits
### Jadeite Forest
> Les forêts perdues de l'îles. Ces grandes forêts primaires sont un endroit courant pour se cacher, avec quelques petites villes.
*(Forêt/Jungle, Marécage)*
- **Stages:**
- **Routes:**
- **Villes:** Numinous Burg
### Obsidian Rock
> Une petite île au large de Moonstone Island, envahi par la corruption et les reste de la Gosth Central.
*(Technologie, "ARK-like", Côte)*
- **Stages:**
- **Routes:**
- **Villes:** Wrath City

View file

@ -1,19 +0,0 @@
## Levels in Sonic Boost game mode
## Correspondance de niveaux (mode classique)
- Niveau 1 : **Jadeite Forest** / **Calcite Hill**
- Niveau 2 : **Diamound Metropolis** / **Agate Park**
- Niveau 3 : **Peridot Archive** / **Zircon Desert**
- Niveau 4 : **Pearl Mountain** / **Carnelian Bridge**
- Niveau 5 : **Graphit Base** / **Moonstone Ruins**
- Niveau 6 : **Garnet Crater** / **Silicon Matrix**
- Niveau 7 : **Obsidian Station** / **Ametist Temples**
- Niveau Bonus : **Crystal Utopia**
## Coupes (mode tournoi)
- Chao Cup : Calcite Hill - ????? - ????? - ?????
- Ring Cup : ????? - ????? - ????? - ?????
- Emerald Cup : ????? - ????? - ????? - ?????
- Master Cup : ????? - ????? - ????? - **Crystal Cosmos**

View file

@ -1,45 +0,0 @@
# Sonic Radiance - Game Design
Sonic Radiance is designed around the idea of what could have been a GBA/DS Sonic RPG. It's inspired by the Sonic Advance saga (especially SAdv3 and Battle), but also by the DS titles.
It also aim to replicate a bit the kind of RPG that where on these console, especially the Pokemon ones (RSE, FRLG, DPP, HGSS, PMD, etc), by having a world offering a lot of stuff to discover and explore, while having a storyline that is simple, yet have stuff to tell.
Samewise, the gameplay aim to not be overly complexe, the game should be easy to pickup and play, but with stuff for people that are ready to get more inside the game. The main story shoudln't be too long to complete for an RPG, but there should be more to do after it.
## General game design
The Game is a turn-based RPG, where character can do multiple action per turn.
### Overworld gameplay
The overworld will be a top-down zelda-inspired map system, where you can use the different capacities of characters to move in maps. The overworld will aim to give the player a sense of reward for getting somewhere, with some puzzle and mini-challenge.
The character should also be able to take damage on the map, and damage should affect the whole team, adding the possibility of dying on the overworld.
### Battle System
The Battle System is a turn-based, Chronicles inspired battle system. Character have QTE in their attacks, making the battle more dynamic. If the player manage to win the QTE, the attack will continue and/or be more powerfull.
It'll also affect the battle ranking and its rewards.
## Quest and story design
The game should be semi-linear, meaning that you have a main quest that advance with time, but with possibilities to do side quest, and some of the main quest, with more freedom.
The story take place on a somewhat isolated Island, and is inspired by the Adventure and Advance eras stories. The lore will be created for this story, but will aim to be somewhat connected to some other elements of the universe.
The aim of the story is to combine the strenght of a Sonic Adventure-style game and from a RPG. The main difference with Sonic Adventure here is that as the game is an RPG, all or most characters have to be part of a same team, instead of having too much of parrallel stories. The idea would be instead of having quest that would be part of different story arcs.
### Main Quests
The main quests will be the quest revolving about the mysteries of Moonstone Island, driven by the characters. The main quests aim to keep the concept of having a "final story" after completing all main stories by having two kind of *main quests* :
- A linear set of main story quests (sometime with two~three objectives to do in any order, but not a lot) that'll go until a "pseudo-final boss" (some equivalent of classic "Sonic Story final boss" like Egg Viper, Egg Wyvern or Egg Dragoon). This set of main story quest would be the equivalent to a combination of Sonic, Tails and Amy storyarc in a more "conventionnal" Sonic Game.
- A set of semi-mandatory arcs that would serve to unlock the final quests. Sometimes they might halt the progress in order to avoid the player to be too OP for the quest ? These quest would be the equivalent of Knuckles, Shadow and Rouge stories in a more "conventionnal".
- After all other main story quest are finished, the last story quests can advance. It's a set of final quest that'll aim to tie all the stories together and to finish all plot points.
### Support quests
When you have some character, you'll be able to unlock *Support Quest*. The quest would have mandatory characters, and the quest would aim to work on their relationships and personnalties.

View file

@ -1,11 +0,0 @@
# Sonic Radiance - Lore
Le Lore de Sonic Radiance contiendra principalement deux éléments : des éléments qui sont spécifiques au jeu, à savoir des éléments sur l'histoire du jeu et la backstory de l'île ou se produit du jeu, et des éléments qui seront spécifique à la vision du monde de Sonic qui est développé dans le jeu.
Le but de ce fichier est de présenter quelques uns des éléments de base qui constituent ce lore :
- **Un jeu centré autour d'un lieu en particulier** : Comme SA (et SA2 dans une moindre mesure ?), le jeu se situe autour d'une histoire bien particulière qui aura des répercutions sur le "général". L'histoire sera situé autour de l'île de Sunlit Island, et le lore sera donc adapté autour de cet histoire.
- **Ambiance typé 2000** : Ce jeu est également un hommage à toute une époque. L'ambiance sera donc à la fois typé Adventure, mais surtout un hommage à tous les "petit Sonic" sorti à cette époque (Advance, Battle, et les jeux mobiles). En découlera une ambiance qui sera unique, et des références à des plot-lines oubliées depuis un moment. Cependant, cela ne veut pas dire que *rien* des jeux récent ne sera adapté ! Certains éléments considérés comme pertinant pour l'histoire ou le gameplay seront présent. Idem pour les éléments du "monde classic", certains seront adapté.
- **Two-World** : Ce jeu utilise le two-world, parce qu'une des sous-intrigue est fondée dessus.

View file

@ -1,72 +0,0 @@
# Backstory : Le projet Gosth Island
## Le projet Millenium, le rêve dune Utopie
Le projet Gosth Island était lun des projets fondé par le « projet Millenium », un projet qui visait à construire partout sur la planète des « villes du futur ». Parmi les autres villes fondées par ce projet, il y a Monopole, Metal City et Grand Metropolis. Ce projet était financé par Rimlight et les Fédérations Unis, et tout un tas dautres acteurs privés. Les Fédérations Unis avaient pour but doffrir un monde meilleurs à tout les habitants de la planète, et empêcher à nouveau les guerres dintervenir. Et le but de ces villes étaient dillustrer la meilleure vie quils auraient tous.
Ils se sont intéressé à Gosth Island, parce quils estimaient que cette nouvelle énergie présente sur lîle serait un moyen de créer une ville comme jamais vu auparavant, qui dépasserait toute les autres, surtout sils réussissaient à faire venir avec eux le peuple qui justement « contrôlait » pour GUN la faille dont provenait lénergie.
## Lachat de Gosth Island
Rimlight sest donc rendu chez les Sidh et leur a proposé un deal : la coalition pour le projet pourrait travailler sur le Stygian Rift, à condition doffrir une compensation financière à tout les membres du peuple qui accepteraient. Ils pourraient alors soit aller vers un autre de leur village, le Sidh Village, soit participer à la construction de la cité du futur et des installations scientifiques.
Le conseil réfléchi plusieurs jours, dans des débats extrêmement tendu. Sur les chefs, une partie étaient pour accepter loffre, une partie contre. Contre toute attente, cest la fille de lun des membres du conseil et une apprentie-prêtresse qui fit basculer la balance en rejoignant elle-même le projet, voulant participer à cette création dune utopie. Son argumentation fit que quatre des membres du conseil furent pour la vente de lîle. Trois encore refusaient :
- Benelos, un grand guerrier, qui estimait le G.U.N. indigne de confiance, et qui refusait de vendre un territoire sacré à des humains. Il estimait que même pour une vie meilleurs, cétait une insulte envers leurs membres, et quil fallait chercher ailleurs les ressources dont ils manquaient cruellement.
- Morrigan, la prêtresse de la Stygian Rift estimait quutiliser comme une source dénergie quelque chose daussi instable les faisait courir à la catastrophe. Lénergie Stygienne était par nature difficile à contrôler, et son aspect corrupteur aurait sans doute des effects catastrophique sur lutopie.
- Lug, le plus jeune des membres du conseil, hésitait. Il estimait que les contreparties étaient très faible, en vue du fait qu'avant l'arrivée des humains sur l'île, ils étaient maître de toutes l'ile.
Cependant, Dahut réussi à convaincre les autres que les risques étaient minimes par rapport à leur situation actuelle : Elle mis en valeur le faible tôt dalphabétisation de leur population, la mortalité infantile très élevée. La jeune femme estimait quils réussiraient avec leur force à préserver leur civilisation dans la modernité, comme la plupars des autres royaumes mobiens. Elle voulait utiliser la modernité comme un moyen pour les Sidh de continuer à exister, parce quelle estimait que simplement lignorer serait juste faire une politique de lautruche jusquà ce quil serait trop tard pour eux et se ferait engloutir parce quils nauraient plus le choix. Lug et Bhain (père de Dahut), rejoignirent le camps de ceux qui étaient pour.
Pendant plusieurs jours, les débats devinrent de plus en plus violent, la situation étant bloqué.
Les débats montèrent en intensité jusquà ce que le conseil fini par accepter sous la pression d'une partie de la population, qui était pour une forme de compromis. Ce fut le père de Dahut qui signa le traité avec les Fédérations Unis, ouvrant le début du projet Gosth Island. La solution trouvée fut de permettre à la fois que les Sidh pratiquent leur culte, et que les FU de faire la centrale, ce en laissant un accès à certaines zones proche de la faille, le tout sous la surveillance d'une "garde commune".
## Des débuts prometteurs mais sous les tensions
Les travaux commencèrent avec pas mal de succès dans les premiers temps. Ils réussirent à extraire et convertir lénergie de la faille, et la centrale fut rapidement opérationnelle. Dahut gagna rapidement un rôle important, puisquelle était celle qui connaissait le mieux le fonctionnement de la faille. Lénergie était plus forte que tout ce que Rimlight avait prévu, et ils comprirent quils pourraient allimenter toute la région avec. Lavancement de la ville se passait bien, et la construction dun dôme capable de recréer des climats impressionnait les masses.
Dans la population de la ville, ce choix cependant divisait. Si une grande partie du peuple voyaient d'abord les conditions de vie, une autre craignait que leur culture disparaisse. Et les deux camps avaient des arguments, et de grand défenseurs. D'un côté Lug et Bhain étaient ceux qui étaient pour le projet. De l'autre Morrigan et Bénélos étaient contre. Cette division provoqua également une division du peuple en deux : une partie dun conseil resta dans le Feral Village pour assurer lordre dans son peuple, tandis que les autres chefs décidèrent d'émigrer avec plusieurs Sidh dans un nouveau village pour participer aux travaux. Le nouveau village fut entièrement financé par Rimlight pour celles et ceux qui voudraient collaborer avec eux.
Cependant, très soucieux d'éviter des conflits, ils commencèrent à construire une route vers à la fois le Nouveau Village et l'Ancien Village, pour les alimenter aussi, notamment après des négociations de Dahut qui estimait que puisquils allaient réussir plus, le peuple Sidh méritait aussi plus. Ce fut accepter, et le Dahut commença à jouir dune excellente réputation parmi les pour. Cependant, cela ne suffit pas. Pour beaucoup d'habitant de l'Ancien Village, ce n'était pas qu'une question de monde de vie : c'était une île sacrée qui était profanée, et une acculturation qui était en train de se produire. Les opposants continuèrent dadresser des critiques au projet, et commencèrent a tenter dalerter la population générale des deux villages sur la situation de leur peuple.
En voyant cela, une partie des cadres du projet avait peur. Ils avaient peur que d'un coup, tout bascule et que tout l'argent dépensé soit dépensé en vain. Certains scientifique craignaient les incidents en cas de conflits. Les Fédérations décidèrent alors de dépécher Ys Gradlon, commandant du GUN, sur le projet afin qu'il pacifie la situation. Ce commandant avait déjà participé à de nombreux conflits, et notamment pas mal de conflits civils. Cepednant, sa stratégie consista alors à essayer de diviser le peuple Sidh entre les pour et les contre, pour pouvoir isoler les contre et éviter leur sentiment de sétendre. Si ce fut efficace, cela crystalisa encore plus les haines.
Cette situation dura plusieurs mois, dans un statut quo où dun côté le projet avançait bien, mais où les critiques étaient toujours plus présente.
Cependant, un incident eut lieu. Un jeune guerrier, Albius, sétait infiltré dans la centrale pour faire un coup déclat. Il fut blessé par balle et plongé dans la faille, directement dans le Stygian Realm. Personne ne sut si le soldat avait fait exprès de jeter le jeune adulte blessé dans la faille ou si c'était un accident. Mais cétait un acte dune violence incroyable pour le peuple Sidh, ce qui provoqua des troubles, et surtout la colère de Morrigan et de Benelos.
Immédiatement, Bénélos indiqua que toute personne qui continuerait à collaborer avec le projet serait banni du peuple. Il lança également un appel à combattre le nouveau général Ys Gradlon, et ses méthodes. La guerre avait été déclarée.
## La bataille de Gosth Island
Une nuit, Benelos attaqua lile avec une armée de soldat. Leur but était simple : reprendre leur territoire. La bataille fit rage pendant des heures, et Benelos alla sattaquer directement à Ys Gradlon, qui avait décidé de garder la faille. Le combat entre les deux fut violent, Ys Gradlon compensant sa faiblesse physique face au mobien bien plus fort par la supériorité de ses armes. En dehors, les soldats du G.U.N. et les guerriers Sidh se battait avec une férocité jamais vue.
La bataille fut remportée par GUN, et les guerriers Sidh furent fait prisonnier. Bénélos cependant neut pas cette chance, sombrant lors du combat dans la faille. Ys Gradlon tenta de sauver son adversaire envers qui malgré leur inimitié il ressentait du respect, voulant lui offrir un procès équitable, mais en vain. Quant à Morrigan, elle tomba au combat, laissant la faille sans prêtre qualifié pour la première fois depuis des siècles, sa fille n'ayant pas eu le temps de terminer son apprentissage.
Le peuple Sidh ne retrouva jamais des forces de batailles pour affronter GUN. Cependant, cet événement eut des conséquences très néfastes sur la stabilité de Gradlon, qui sombra petit à petit dans la paranoïa.
## La démesure de Gradlon
Ys Gradlon déclara que le projet devait passer entièrement sous contrôle de GUN. Si dans les faits toutes les sociétés qui travaillaient sur le projet pûrent continuer, lile se militarisa de plus en plus. Les habitants du peuple Sidh sur lile furent déplacé dans des dortoirs, afin de sassurer de labsence de traître. Il commença à sintéresser également aux application militaire du projet. Il considérait lattaque des Sidh comme une trahison envers la Fédération même, et commença a craindre plus dennemi intérieurs. Faisant des cauchemars chaque nuit, devenant de plus en plus méfiant, il garda le même but quavant protéger les Fédérations Unis et ses habitants mais devint prêt à le faire à tout prix.
Il fit étudier le Stygian Realm, et la manière dont la faille pouvait happer êtres vivants, songeant aux possibilités de lutiliser pour faire disparaître des « ennemis des United Federation » (cest-à-dire les forces militaires opposées à lunification des états dans la Fédération, les grands bandits, et les groupes terroristes). Il voyait cette dimension comme « la prison ultime », puisque ce serait une prison ou il serait impossible de sévader, à cause de la corruption provoqué par le Styx. Il commença à théoriser qu'en fin de compte, les mobiens n'étaient rien de plus que des aliens proche à envahir la Terre.
Ce fut à ce moment là que Dahut commença a se rebeller. Elle refusa de coopérer, estimant quune telle prison était contraire à ce que la Fédération Unie et leur projet tenaient. Ys Gradlon sénerva, et fit emprisonner Dahut. Le Syphon dEnergie du Gosth Core fut maintenu par une plus petite équipe, dont une partie des membres était dévoué à garantir la stability du Stygian Rift.
Ys Gradlon fit construit une armée de satellite, les Erinyie, capable de capter lénergie de la centrale et de se la transmettre, afin de créer une armada de satellite capable de toucher nimporte quel point de la terre. Les forces automatisé de construction furent lancé en orbite, et les Fédérations Unis seraient doté de la capacité de frapper partout sur la Terre, à nimporte quel moment.
Les Fédérations Unis seraient désormais protégée de toute menace.
## La fin du projet.
Cependant, Dahut fini par réussir à sévader. Elle vit ce quétait devenu le projet : en place de ville du futur, dutopie pour lavenir, il ny aurait quune arme ultime. Elle décida alors de détruire toute lœuvre de sa vie ce pour quoi elle avait été même prête à trahir sa famille et possiblement se tuer avec : Saboter la Gosth Central, pour mettre fin définitivement au projet.
Les humains la retrouvèrent en train de saboter plusieurs parties de la centrale, brisant tuyaux, détruisant machines de contrôles. Avait-elle pour but de faire exploser la centrale ? Elle fut attrapé après son œuvre, et exécutée après son refus de dire comment réparer ce quelle avait fait. Cependant, Gradlon refusa dévacuer lîle, et ordonna de couper la centrale le temps de réparer les dégats.
Ce fut là que lincident se produisit. Dahut avait réussi à placer au fond du Stygian Altar, dans une petite crypte quaucun humain ne connaissait, un appareil de sa création. Un petit appareil qui capitait lénergie et la renvoyait, de sorte à faire saturer toute lénergie Stygienne. Comme un immense court-circuit dénergie, à lintérieur même de la faille. Cela provoquerait le même phénomène de « happe » qui avait touché Bénélos et quutilisait Gradlon, mais à léchelle de lile entière. Les sabotages navaient été quune couverture à sa véritable action, et la machine navait pas été retrouvée.
La saturation dénergie se produisit donc, et, en une fraction de seconde, il ne resta plus un seul humain ou sidh sur lîle de Gosth Island. De la corruption se retrouva jusqu'au côtes de l'île principale. De nombreux dégats furent produits sur les mini-générateurs Chaotique de Sunlit Island également. Face à la disparition de leur commandant, et à la perte de toutes les personnes savant faire fonctionner lîle, elle fut désaffectée, et lîle passa sous surveillance de GUN pendant 12 ans.
Ce fut la fin du projet Millenium.

View file

@ -1,61 +0,0 @@
# Sonic Radiance - Peuple Sidth
Le peuple Sidh est un peuple de Mobien hétéroclite qui vit sur l'île de Sunlit Island. Ayant autrefois occupé toute l'île, ainsi que la petite île au large de Gosth Island, ils ne vivent aujourd'hui que dans le XXXXXX Village, suité dans les plaines de XXXXX.
Plus qu'un peuple basé sur une race (genre les échidnés), ils sont plus réunis par une culture. Basée sur une culture celtique (notamment les mythologies Bretonne, Irlandaise, Galloise et Ecossaise), les personnages de ce peuple ne sont pas nommés suivant la base normale de Sonic (des mots anglais), mais selon des termes de la culture visée (ici des dieux ou mots celtes), un peu comme Tikal et Pachacamac ont des noms basé sur des temples améridiens.
Leur rôle dans l'intrigue sera un peu ambigüe, notamment à travers les personnages de *Taranis*, *Ankou* ou *Anrad*. Leur nom vient du nom du *Sidh*, royaume des morts chez les Celtes.
## Culture et mode de vie
Vivant dans leur village, dans les plaines et juste avant le XXXX (qu'ils protègent des intrus). Ils vivent principalement en autarcie, et ont une grande méfiance pour les humains. Ils accepteront même de s'allier avec Eggman en échange de vivre et de soutiens financier (estimant que la guerre contre Eggman est une affaire d'humain).
Aujourd'hui, ils protègent surtout le Super Warp Ring qui se trouve dans les cavernes au fond de leur vallée.
Panthéïstes, ils croient en la *Grande Mère*, qui est une déesse de la nature qui est présente en chaque endroit en chaque instant. De ce fait, ils vénèrent tout ce qui est surnaturel, et proche du Chaos, la principale des forces naturelles. En cela, ils ont longtemps vénéré le Stygian Rift situé sur l'île de Gosth Island, qu'ils alimentaient en sacrifice jusqu'à ce qu'ils soient exproprié de l'île de Gosth Island, lors de la construction de la Gosth Central
La "faille noire" comme ils l'appelle reste aujourd'hui encore ce qu'ils vénèrent le plus, et cette expropriation est source de leur colère contre les Fédérations Unis.
Leur chef actuel est Lug, père de Taranis et Anrad, qui est prêt à tout ce qu'il faudra pour aider ses enfants et surtout son peuple.
### Le second village
Il existe un second village, se trouvant au niveau des plages du sud. Ce village est constitué des Sidh ayant désiré participé dans le projet Gosth Island et n'ayant pas péri lors de l'incident.
Les villageois du second village (surnommé le village de *Bhàin*) vivent principalement du revenu du tourisme, et sont assez pauvre mais restent attaché à leur indépendance et à leur mode de vie.
Cependant, ils sont beaucoup moins attaché au fait de rester séparer des humains, et sont considéré par leur pairs du village principal comme des traitres.
## Histoire du peuple Sidh
### Les premiers Sidh
Le peuple Sidh sont à lorigine un groupe de mobien hétéroclite qui sest installé sur lîle, qui était déserte à lorigine, il y a très longtemps par le Super Warp Ring. Suivant un petit groupe de penseurs, les Sages, ils fondèrent une société, visant à vivre suivant leur vertu et leurs idéaux. Fondée sur la pensée et la recherche du bien absolu, ils ont fondé une civilisation surtout centrée sur la discussion et la présence de ces Sages qui devaient conduire les débats et faire évoluer la science.
Tous les sages et les chefs se devaient de passer quatre épreuve, liées aux quatre vertues cardinales (le courage, la tempérence, la justice et la sagesse). Leur but était de créer une civilisation d'être qui auraient atteint l'état de perfection morale. Cependant, dans leur vision, ils avaient également un aspect "pédant". S'ils voulaient aider les autres, ils avaient tendance à voir de haut les peuples "moins intelligents"
Petit à petit, ils sont devenus une civilisation bénévole et qui a eut de grande avancées techniques, à la manière des Chozos de Metroid. Ils découvrirent sur la petite île de Gosth Island au large de leur île principale la *Chaos Vein*, qu'ils commencèrent à étudier. C'est eux qui sont à l'origine de tous les temples et technologies anciennes qui se trouvent sur l'île. Leur but était d'utiliser la technologie de la faille pour améliorer la santé de leur peuple, ainsi que de facilité la vie des différents peuples.
### La chute
Cependant, ce qui a été la source de leur brillance fut celle aussi de leur fin, à cause de la corruption de la Chaos Vein. En effet, vers la fin de l'île, un groupe de sage commença un nouveau projet. Leur but était de créer un pouvoir qui vaincrait la malchance et l'infortune, la maladie et la peur. Leur but n'était pas de "vaincre la mort" ou d'autres choses du genre, mais de créer une énergie qui apporterait à tous santé et bonne fortune.
Mais une chose leur manquait. La puissance. La Chaos Vein leur apportait énormément de puissance, mais ce n'était pas suffisant pour leur plan. Cela provoqua chez les sages qui travaillait sur le plan une dispute. Que faire ? Des tas de possibilités existaient. Faire une arme provoquant méfortune, et aller chercher d'autres failles ? Abandonner le projet et se contenter des améliorations déjà présente ? Leur choix fut tout autre.
Les Sidh tentèrent de faire évoluer la Chaos Vein afin de pouvoir avoir plus d'énergie. Utilisant un dispositif pour centrer l'énerige de la faille, cette machine s'emballa, provoquant une catastrophe. Cela provoqua l'évolution du Chaos en une autre force, le Styx. Cette énergie corrompu commença a tout envahir, et la faille commença a happer des êtres vivants.
### La période sombre et la reconstruction
Le peuple Sidh, ayant perdu une grande partie de son peuple et de sa civilisation, ne survécu pas en tant que civilisation. Il s'effondra progressivement, et bientôt ne resta de l'ancienne époque qu'un souvenir lointant, celui de l'époque ou le peuple Sidh était "proche des dieux".
Ils commencèrent à craindre et à vénérer la Chaos Vein, désormais devenu le Stygian Rift. Entendant ses murmures, ils le voyaient comme une émanation maléfique de la puissance naturelle. Ils y ont longtemps conduit des sacrifices. Cependant, cela ne fit qu'augmenter la voracité et l'instabilité de la faille, jusqu'à ce qu'ils approchent de l'extermination à cause de cette voracité.
Les quelques sages qui restaient continuèrent à faire les épreuves et à conduire la civilisation, mais ne connaissaient que de moins en moins les origines de leur culture. Ils s'isolèrent de plus en plus du monde, conscient d'avoir été à l'origine de la naissance d'un danger, et effrayé par ce danger. Ce n'était pas qu'ils ne comprenaient pas ce danger ou qu'ils étaient stupide : ils étaient effrayé, et n'avaient plus le choix.
Ce fut lorsque la civilisation approcha encore de la chute qu'une des sages décida de tenter autre chose *Dana*, toute sa vie, elle étudia et appris de la faille, avec ses collègues, jusqu'à aller affronter la faille pour la calmer. Elle réussi à apaiser la faille, devenant la première des pretresses de la faille.
Petit à petit, les sages et les rituels disparurent, remplacé petit à petit par un conseil, qui prenait les décisions avec le reste du peuple. Le peuple continua à exister, et évolua perdant son accès à ses technologies. L'île de Gosth Island devint une île sacrée. Les prêtres de la faille continuèrent à exister, et cet état de fait évolua, jusqu'à ce qu'arrive le *projet Millienium* il y a quinze ans.
En effet, l'incident du projet Millienium provoqua le décès d'une partie du conseil, et la perte de Gosth Island qui devint une île interdite, protégée militairement par les *GUN*. Il ne resta du conseil plus qu'un des chefs (Lug, le chef actuel), une chef existant à l'état spectral (Morrigan) et une fille de chef supposée vivante mais disparue depuis l'incident de Gosth Island. (Dahut)
Le peuple vit aujourdhui divisé, dans une certaine précarité, et une partie sest tourné récemment vers Eggman, lui offrant des connaissance sur le Stygian Rift en échange de nourriture, de médicament et de vengeance pour certains. Les survivants de l'incident ayant été membres du projet furent bannis, et fondèrent un petit village sur la côte, vivant désormais des revenus touristiques.

View file

@ -1,35 +0,0 @@
## Les Fédérations Unis
Les Fédérations Unis sont une république parlementaire avec un régime présidentiel. Puissante nation, elle a subit cependant plusieurs crise depuis les attaques du Docteur *Ivo « Eggman » Robotnik*.
Elles peuvent être vu comme quelque chose entres les Nations-Unis et les États-Unis. Le but de cet état est de garantir un développement tout en respectant les libertés des pays qui en font partie (et qui conserve une certaine indépendance). L'île de Sunlit Island est une colonie des Fédérations Unis, avec comme représentant le maire de la ville de *Sunlit Metropolis*.
Leur technologie est majoritairement contemporaire, mais a réussi de grande avancée depuis 50 ans à l'aide des technologies chaotique, en grande partie découvertes par le professeur Gérald
Dans le jeu, les Fédérations Unis, n'ont pas une présence très forte dans le jeu, en tout cas pas directement.
## Les Gardian Units of Nations
Les Gardian Units of Nations (ou G.U.N. parfois orthographié en GUN) sont la principale force militaire des Fédérations Unis, et ont comme rôle de protéger à la fois les Fédérations Unis, et à la fois les pays alliés. Cette armée est dirigé par un Commandant.
L'armée est actuellement en grande partie dédiée à affronter le Dr. Ivo Robotnik, qui vise à conquérir le monde, mais narrive pas à le localiser et à lancer des attaques précises. La capacité à disparaître de ce savant étant déconcertante, et ses moyens encore inconnus. L'inefficacité de GUN à vaincre les menances originaire du monde des animaux est la source d'une méfiance chez certaines personnes.
## Rimlight, les Chaos Central et les Chaos Vein
La société Rimlight est lun des éléments scénaristique important du jeu. Holding co-détenu par des actionnaires privés et par le GUN, la société recherche dans le domaine des énergies propres, et plus précisément dans le domaine des énergies chaotiques.
Ils utilisent notamment pour cela les thèses de Gerald Robotnik sur ce type dénergie, quand il était chercheur à luniversité de Central City, thèses qui avaient conduit Gerald à faire des recherches sur les civilisations anciennes échidnés, pour mieux comprendre leur rapport à lénergie chaotique (doù les découvertes sur Chaos, la prophétie échidné, Gizoïd…) et le fait quil fut choisit comme chef de léquipe du projet Shadow. Ils sont les producteurs des Chaos Drive, et des Chaos Central.
### Les Chaos Central
Les Chaos Central sont une source dénergie de plus en plus présente sur toute la planète. Construite sur des zones nommées les Veines Chaotiques (Chaos Vein) et sont utilisées depuis environs vingt ans (pour le marché publique) à vingt-cinq ans (pour les Guardian Units of Nations). Lénergie produite par les Chaos Central revet deux forme : léléctricité, ou les Chaos Drives, des batteries chaotiques extrêmement durable utilisée notamment par les mécha des Guardian Units of Nations.
Lintérieur dune centrale chaotique est cependant un endroit dangereux à cause de linfluence de lénergie chaotique et de sa transformation en électricité ou en *Chaos Shard* pour les Chaos Drive, et est réservé à des connaisseurs de lénergie chaotique. Le cœur dune centrale chaotique, nommé le *Chaos Core*, est un endroit ou lénergie circule suivant des patterns très précis.
Cest la deuxième source dénergie la plus utilisée, après lénergie thermique liquide produite par la société HexaECO, utilisée depuis à peu près la même période.
### Les Chaos Vein
Les Chaos Vein (Veines Chaotiques) sont la source de lénergie utilisée dans les Chaos Central du conglomérat Rimlight. Il sagit de zones démission spontanée dÉnergie Chaotique qui existent à quelques endroits de la planète, relativement rares mais trouvable sur tout les continents. Même si ces failles sont rien face à des Chaos Emerald, il est possible de produire de une énergie propre et durable à laide de ces failles. Quand elles ne sont pas sur-exploité (comme ce qui est arrivé dans un incident avec lune des premières centrales chaotiques), ces failles sont contrairement au Chaos Emerald particulièrement docile à utiliser.
Les Chaos Vein sont des failles vers des univers-bulles qui leur sont propre (des sortes de Special Zone à petite échelle, mais qui ne contiennent pas de Chaos Emerald) et qui est la source de cette énergie. Cest ce qui fait laspect durable et stable à la fois de cette énergie : seul très peu dénergie séchappe de la veine, mais la reserve quil y a derrière est largement au dessus de toute la consommation humaine planétaire depuis les débuts de la révolution industrielle, au bordure de limmesurable.

View file

@ -1,7 +0,0 @@
## Sonic Radiance - Synopsis
L'histoire de Sonic Radiance se passe sur l'île de Moonstone Island, une petite île tempérée sous contrôle des Fédérations Unis. Cette île a longtemps cependant été le centre d'une civilisation mobienne appellée le *peuple Sidh*.
Sonic, Tails et Amy (équipe de début de jeu) arrivent sur l'île suite à un appel du *Gouverneur de Moonstone Island*, qui est inquiet de l'arrivée massive de robot d'Eggman sur l'île. Il a alors demandé de l'aide aux trois mobiens pour qu'ils se débarrassent de la présence du savant fou.
Cependant, l'île recèle bien des mystères, et Sonic & compagnies comprendront bien vite qu'on ne peut comprendre la menace présente que subit l'île, sans découvrir son passé...

View file

@ -1,23 +0,0 @@
# Subquest - ideas
**Note** : une partie de ses sous-quêtes auraient besoin d'être adaptée pour Radiance, ayant été crée à l'origine pour le fangame Boost, un fangame plus orienté "mobile"
---
- **The last of his kind** -- une histoire (peut-être en plusieur partie ?) où Shadow et Knuckles doivent travailler ensemble pour traquer le dernier Shadow Android. Knuckles ressent un peu de compassion envers le robot (qui a une conscience, et qui doit faire avec le fait de ne pas être Shadow et de savoir que le vrai Shadow à détruit une grande partie de son "espèce"), sachant ce que c'est d'être le dernier de son espace
- **Frozen Earth Theory** -- un event spécial noel, où Eggman à décidé de refroidir la planète comme chantage mondial, en précisant bien les riques pour les recoltes, l'alimentation, etc… Particularité graphique de ce scénario : Tout les niveaux utilisent les tiles de neige de Pearl Mountain.
- **Phantom Doll** -- Event special halloween : Tails Doll à récupéré un prototype de Phantom Ruby. Ouch.
- **The Chaos Breakers** -- La Team Dark est appellé sur Terre pour affronter de nouveaux ennemis, qui menace le portail dimensionnel : Les Chaos Breakers. Cette faction rebelle de GUN estime que les mobiens étant des aliens, on ne peut pas leur faire confiance, et qu'ils ont déjà apporté le chaos sur Terre.
- Un scénario Rouge + Amy
- Un scénario Cream + Omega
- Un scénario special saint-velentin Omega + Blaze :DDD
- Une série de scénario où GUN travaille pour connecter le monde de Blaze aux deux autres… malheureusement, des soucis se passeront.
- Scénario post-Forces avec l'explication de pourquoi GUN n'a pas aidé Mobius/le monde des animaux pendant l'invasion d'Eggman.

View file

@ -23,6 +23,9 @@
function love.update(dt) function love.update(dt)
core:update(dt) core:update(dt)
if (game ~= nil) then
game:update(dt)
end
end end
function love.draw() function love.draw()

View file

@ -0,0 +1,68 @@
-- indexedrect.lua :: An indexed rectangle is a rectangle indexed to a point,
-- Basically a rectangle that have its coordinate recalculated from an existing
-- point
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Rect = require "birb.classes.2D.rect"
local IndexedRect = Rect:extend()
function IndexedRect:new(origin, ox, oy, w, h)
self.setOrigin(origin)
self.ox = ox
self.oy = oy
local x, y = self:getPosition()
IndexedRect.super.new(self, x, y, w, h)
end
function IndexedRect:setRelativePosition(ox, oy)
self.ox = ox or self.ox
self.oy = oy or self.oy
end
function IndexedRect:setOrigin(origin)
self.origin = origin
-- We should check if the origin is really a point
end
function IndexedRect:getOrigin(origin)
return self.origin
end
function IndexedRect:getPosition()
return self.origin.x + self.ox, self.origin.y + self.oy
end
function IndexedRect:updateRect()
local x, y = self:getPosition()
self:setPosition(x, y)
return x, y, self.w, self.h
end
function IndexedRect:modify(ox, oy, w, h)
self.ox = ox
self.oy = oy
self:setSize(w, h)
self:updateRect()
end
return IndexedRect

View file

@ -0,0 +1,71 @@
-- point.lua :: a 2D point.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Point = Object:extend()
function Point:new(x, y)
self.x, self.y = x, y
end
function Point:setPosition(x, y)
self.x, self.y = x, y
end
function Point:goToward(x, y)
local x = x or 0
local y = y or 0
self:setPosition(self.x + x, self.y + y)
end
function Point:getPosition()
return self.x, self.y
end
function Point:getDistance(x, y)
return utils.math.pointDistance(self.x, self.y, x, y)
end
function Point:getDistanceFromPoint(other)
local x, y = other:getPosition()
self:getDistance(x, y)
end
function Point:getDirection(x, y)
return utils.math.pointDirection(self.x, self.y, x, y)
end
function Point:getDirectionFromPoint(other)
local x, y = other:getPosition()
self:getDirection(x, y)
end
function Point:getMiddlePoint(x, y)
return utils.math.getMiddlePoint(self.x, self.y, x, y)
end
function Point:getMiddlePointFromPoint(other)
local x, y = other:getPosition()
self:getMiddlePoint(x, y)
end
return Point

View file

@ -0,0 +1,74 @@
-- rect.lua :: a 2D rectangle.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Point = require "birb.classes.2D.point"
local Rect = Point:extend()
function Rect:new(x, y, w, h)
Rect.super.new(self, x, y)
self:setSize(w, h)
end
function Rect:set(x, y, w, h)
self:setPosition(x, y)
self:setSize(w, h)
end
function Rect:setSize(w, h)
self.w = w or self.w
self.h = h or self.h
end
function Rect:getArea()
local x, y = self:getPosition()
return x, y, self.w, self.h
end
function Rect:getShape()
return self:getArea()
end
function Rect:getCorners()
local x, y, w, h = self:getArea()
return x, y, x + w, y + h
end
function Rect:getCenter()
local x, y, w, h = self:getArea()
return math.floor(x + (w/2)), math.floor(y + (h/2))
end
function Rect:areCoordInside(dx, dy)
local x, y, w, h = self:getArea()
return ((dx > x) and (dx < x + w) and (dy > y) and (dy < y + h))
end
function Rect:getRelativeCoordinate(dx, dy)
return dx - self.x, dy - self.y
end
function Rect:drawBox()
utils.graphics.box(self.x, self.y, self.w, self.h)
end
return Rect

View file

@ -0,0 +1,71 @@
-- box.lua :: a 3D box.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Point = require "birb.classes.3D.point3D"
local Box = Point:extend()
function Box:new(x, y, z, w, h, d)
Box.super.new(self, x, y, z)
self:setSize(w, h, d)
end
function Box:setSize(w, h, d)
self.w = w or self.w
self.h = h or self.h
self.d = d or self.d
end
function Box:getArea()
local x, y, z = self:getPosition()
return x, y, z, self.w, self.h, self.d
end
function Box:getShape()
local x, y, z, w, h, d = self:getArea()
return x, y-z-d, w, h+d
end
function Box:getCorners()
local x, y, z, w, h, d = self:getArea()
return x, y, z, x + w, y + h, z + d
end
function Box:getCenter()
local x, y, z, w, h, d = self:getArea()
return math.floor(x + (w/2)), math.floor(y + (h/2)), math.floor(z + (d/2))
end
function Box:areCoordInside(dx, dy, dz)
local x, y, z, w, h, d = self:getArea()
return ((dx > x) and (dx < x + w) and (dy > y) and (dy < y + h)) and (dz > z) and (dz < z + d)
end
function Box:getRelativeCoordinate(dx, dy, dz)
return dx - self.x, dy - self.y, dz - self.z
end
function Box:drawBox()
utils.graphics.box(self.x, self.y, self.w, self.h)
end
return Box

View file

@ -0,0 +1,71 @@
-- indexedbox.lua :: An indexed box is a box indexed to a point,
-- Basically a box that have its coordinate recalculated from an existing
-- point
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Rect = require "birb.classes.2D.rect"
local IndexedRect = Rect:extend()
function IndexedRect:new(origin, ox, oy, oz, w, h, d)
self.setOrigin(origin)
self.ox = ox
self.oy = oy
self.oz = oz
local x, y, z = self:getPosition()
IndexedRect.super.new(self, x, y, w, h)
end
function IndexedRect:setRelativePosition(ox, oy, oz)
self.ox = ox or self.ox
self.oy = oy or self.oy
self.oz = oz or self.oz
end
function IndexedRect:setOrigin(origin)
self.origin = origin
-- We should check if the origin is really a point
end
function IndexedRect:getOrigin(origin)
return self.origin
end
function IndexedRect:getPosition()
return self.origin.x + self.ox, self.origin.y + self.oy, self.origin.z + self.oz
end
function IndexedRect:updateBox()
local x, y, z = self:getPosition()
self:setPosition(x, y, z)
return x, y, self.w, self.h, self.d
end
function IndexedRect:modify(ox, oy, oz, w, h, d)
self.ox = ox
self.oy = oy
self.oz = oz
self:setSize(w, h, d)
self:updateBox()
end
return IndexedRect

View file

@ -0,0 +1,72 @@
-- point3D.lua :: a 3D point.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Point = Object:extend()
function Point:new(x, y, z)
self.x, self.y, self.z = x, y, z
end
function Point:setPosition(x, y, z)
self.x, self.y, self.z = x, y, z
end
function Point:goToward(x, y, z)
local x = x or 0
local y = y or 0
local z = z or 0
self:setPosition(self.x + x, self.y + y, self.z + z)
end
function Point:getPosition()
return self.x, self.y, self.z
end
function Point:getDistance(x, y, z)
return utils.math.pointDistance3D(self.x, self.y, self.z, x, y, z)
end
function Point:getDistanceFromPoint(other)
local x, y, z = other:getPosition()
self:getDistance(x, y, z)
end
function Point:getDirection(x, y)
return utils.math.pointDirection(self.x, self.y, x, y)
end
function Point:getDirectionFromPoint(other)
local x, y = other:getPosition()
self:getDirection(x, y)
end
function Point:getMiddlePoint(x, y, z)
return utils.math.getMiddlePoint3D(self.x, self.y, self.z, x, y, z)
end
function Point:getMiddlePointFromPoint(other)
local x, y, z = other:getPosition()
self:getMiddlePoint(x, y, z)
end
return Point

View file

@ -0,0 +1,139 @@
-- classes/serializable :: a serializable object, can give its field as data
--[[
Copyright © 2021 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Serializable = Object:extend()
function Serializable:new(serializeFields, listSerializable)
self.serializeFields = serializeFields
self.listSerializable = listSerializable
end
function Serializable:getData()
local data = {}
-- We serialize all fields
if (self.serializeFields ~= nil) then
for _, key in ipairs(self.serializeFields) do
data[key] = self:wrapField(key)
end
end
-- We serialize all list of serializable
if (self.listSerializable ~= nil) then
for _, key in ipairs(self.listSerializable) do
data[key] = self:wrapList(key)
end
end
return data
end
function Serializable:wrapField(key)
local serializedField = self[key]
if (serializedField ~= nil) then
if (type(serializedField) == "table" and serializedField.is ~= nil) then
if (serializedField:is(Serializable)) then
serializedField = serializedField:getData()
serializedField.isSerializable = true
end
end
self:print(key, serializedField, false)
return serializedField
end
end
function Serializable:wrapList(key)
local serializedList = {}
serializedList.isListSerializable = true
for listKey, listElement in pairs(self[key]) do
serializedList[listKey] = listElement:getData()
end
self:print(key, serializedList, false)
return serializedList
end
function Serializable:setData(data)
for key, value in pairs(data) do
if (key ~= "serializedField") then
self:unwrapField(key, value)
end
end
self:finishDeserialization()
end
function Serializable:unwrapField(key, value)
local serializedField = value
if (serializedField ~= nil) then
if (type(serializedField) == "table") then
if (serializedField.isSerializable == true) then
self[key]:setData(serializedField)
elseif (serializedField.isListSerializable) then
self:unwrapList(key, serializedField)
else
self[key] = serializedField or self[key]
end
else
self[key] = serializedField or self[key]
self:print(key, serializedField, true)
end
end
end
function Serializable:unwrapList(key, list)
if (list == nil) then
error("List " .. key .. " shouldn't be null in the save")
end
for listKey, listElement in pairs(list) do
if (listKey ~= "isListSerializable") then
self[key][listKey]:setData(listElement)
end
end
self:print(key, list, true)
end
function Serializable:print(key, value, isLoading)
local loadString = "Loading "
if (isLoading == false) then
loadString = "Saving "
end
local valueString = value
if type(valueString) == "boolean" then
if valueString then
valueString = "true"
else
valueString = "false"
end
end
if (type(value) == "table") then
valueString = utils.table.toString(value)
end
loadString = loadString .. key .. " " .. ": " .. valueString
if (core ~= nil) then
core.debug:debug("serializable", loadString)
else
print("serializable", loadString)
end
end
function Serializable:finishDeserialization()
-- Empty function callback
end
return Serializable

View file

@ -0,0 +1,73 @@
-- classes/serializable/serializer :: a serializer, able to put stuff into a bin file
--[[
Copyright © 2021 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Serializable = require "birb.classes.serializable"
local Serializer = Serializable:extend()
local binser = require("birb.libs.binser")
function Serializer:new(serializeFields, listSerializable)
Serializer.super.new(self, serializeFields, listSerializable)
end
function Serializer:reset()
end
function Serializer:delete(filename)
local filepath = self:getFile(true, filename)
if utils.filesystem.exists(filename) then
love.filesystem.remove(filepath)
end
end
function Serializer:deserialize(filename)
local filepath = self:getFile(true, filename)
if utils.filesystem.exists(filename) then
local loadedDatas = binser.readFile(filepath)
self:setData(loadedDatas[1])
else
self:reset()
end
end
function Serializer:serialize(filename)
local data = self:getData()
local filepath = self:getFile(true, filename)
binser.writeFile(filepath, data)
end
function Serializer:getFile(absolute, filename)
local dir = ""
if absolute then
dir = love.filesystem.getSaveDirectory() .. "/"
if (not utils.filesystem.exists(dir)) then
love.filesystem.createDirectory("")
end
end
local filepath = dir .. filename
return filepath
end
return Serializer

View file

@ -1,7 +1,32 @@
-- time.lua :: a timer, tweener and timed switch handler.
-- This class need birb.libs.tween to work
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local TweenManager = Object:extend() local TweenManager = Object:extend()
local tween = require "game.modules.tweenmanager.libs.tween" local tween = require "birb.libs.tween"
local Timer = require "core.modules.world.actors.utils.timer" local Timer = require "birb.classes.time.timer"
function TweenManager:new(subject) function TweenManager:new(subject)
self.subject = subject self.subject = subject

View file

@ -1,4 +1,4 @@
-- core/debug.lua :: Debug functions for the core system. -- core/debug.lua :: The basic internal debug framework of the birb engine.
--[[ --[[
Copyright © 2019 Kazhnuz Copyright © 2019 Kazhnuz
@ -23,12 +23,20 @@
local DebugSystem = Object:extend() local DebugSystem = Object:extend()
local cwd = (...):gsub('%.debug$', '') .. "." local lovebird = require "birb.libs.lovebird"
local lovebird = require(cwd .. "libs.lovebird")
function DebugSystem:new(controller, active) local Levels = enum {
"ERROR",
"WARNING",
"INFO",
"DEBUG"
}
function DebugSystem:new(controller)
self.controller = controller self.controller = controller
self.active = active or false
self.debugLevel = self.controller.conf.debugLevel or Levels.INFO
self.active = (self.debugLevel == Levels.DEBUG)
if (self.active) then if (self.active) then
lovebird.update() lovebird.update()
end end
@ -43,27 +51,39 @@ end
-- PRINT FUNCTIONS -- PRINT FUNCTIONS
-- Print and log debug string -- Print and log debug string
function DebugSystem:debug(context, string)
self:log(Levels.DEBUG, context, string)
end
function DebugSystem:print(context, string) function DebugSystem:print(context, string)
if (self.active) then self:log(Levels.INFO, context, string)
print(self:getLogLine("DEBUG", context, string))
end
end end
function DebugSystem:warning(context, string) function DebugSystem:warning(context, string)
if (self.active) then self:log(Levels.WARNING, context, string)
print(self:getLogLine("WARNING", context, string))
end
end end
function DebugSystem:error(context, string) function DebugSystem:error(context, string)
error(self:getLogLine("ERROR", context, string)) self:log(Levels.ERROR, context, string)
error(self:getMessage(": ", context, string))
end end
function DebugSystem:getLogLine(type, string1, string2) function DebugSystem:log(level, context, string)
if (self.debugLevel >= level) then
print(self:getLogLine(Levels[level], context, string))
end
end
function DebugSystem:getLogLine(type, context, string)
local head = self.controller:getIdentity(false) .. "|" .. os.date("%x-%X") .. "|" .. type .. "|"
return head .. self:getMessage("|", context, string)
end
function DebugSystem:getMessage(separator, string1, string2)
if (string2 == nil) then if (string2 == nil) then
return "[" .. type .. "] " .. string1 return string1
else else
return "[" .. type .. "] " .. string1 .. ": " .. string2 return string1 .. separator .. string2
end end
end end

View file

@ -25,13 +25,6 @@
local cwd = (...):gsub('%.init$', '') .. "." local cwd = (...):gsub('%.init$', '') .. "."
-- GLOBAL UTILS/FUNCTION LOADING
-- Load in the global namespace utilities that'll need to be reusable everywhere
-- in the game
Object = require(cwd .. "libs.classic")
utils = require(cwd .. "utils")
local CoreSystem = Object:extend() local CoreSystem = Object:extend()
local DebugSystem = require(cwd .. "debug") local DebugSystem = require(cwd .. "debug")
@ -41,25 +34,47 @@ local Input = require(cwd .. "input")
local Screen = require(cwd .. "screen") local Screen = require(cwd .. "screen")
local Lang = require(cwd .. "lang") local Lang = require(cwd .. "lang")
local SceneManager = require(cwd .. "scenemanager") local SceneManager = require(cwd .. "scenemanager")
local MusicManager = require(cwd .. "music")
require(cwd .. "callbacks")
-- INIT FUNCTIONS -- INIT FUNCTIONS
-- Initialize and configure the core object -- Initialize and configure the core object
function CoreSystem:new(DEBUGMODE) function CoreSystem:new()
self.debug = DebugSystem(self, DEBUGMODE) self:setDefaultConf()
self.debug = DebugSystem(self)
self.options = Options(self) self.options = Options(self)
self.input = Input(self) self.input = Input(self)
self.screen = Screen(self) self.screen = Screen(self)
self.scenemanager = SceneManager(self) self.scenemanager = SceneManager(self)
self.lang = Lang(self) self.lang = Lang(self)
self.music = MusicManager(self)
end
function CoreSystem:setDefaultConf()
self.conf = {}
self.conf.window = {}
self.conf.modules = {}
love.conf(self.conf)
end end
function CoreSystem:registerGameSystem(gamesystem) function CoreSystem:registerGameSystem(gamesystem)
self.game = gamesystem self.game = gamesystem
end end
function CoreSystem:getDefaultConf()
return self.conf
end
function CoreSystem:getIdentity(versionned)
local identity = self.conf.identity or "birbengine"
if (versionned) then
local version = self.conf.gameversion or 0
identity = identity .. "-" .. version
end
return identity
end
-- MOUSE FUNCTIONS -- MOUSE FUNCTIONS
-- get directly the mouse when needed -- get directly the mouse when needed
@ -100,6 +115,7 @@ function CoreSystem:update(dt)
self.scenemanager:update(dt) self.scenemanager:update(dt)
self.screen:update(dt) self.screen:update(dt)
self.music:update(dt)
end end
-- DRAW FUNCTIONS -- DRAW FUNCTIONS

View file

@ -0,0 +1,103 @@
-- core/music.lua :: A music system, in order to add some usefull features
-- and to make music not scene dependant
--[[
Copyright © 2020 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local MusicManager = Object:extend()
function MusicManager:new(core)
self.core = core
self.musics = {}
self.isPlaying = false
self.playNextMusic = false
end
function MusicManager:update(dt)
if (self.isPlaying and (self.musics[1] ~= nil)) then
if (not self.musics[1]:isPlaying()) then
if (self.playNextMusic and (self.musics[1] ~= nil)) then
self:skip()
self:playMusic()
self.playNextMusic = false
else
self.isPlaying = false
end
end
end
end
function MusicManager:getCurrentMusic()
return self.musics[1]
end
function MusicManager:haveMusic()
return (self.musics[1] ~= nil)
end
function MusicManager:playMusic()
if (self:haveMusic()) then
self.musics[1]:setVolume(self.core.options.data.audio.music / 100)
love.audio.play( self.musics[1] )
self.isPlaying = true
end
end
function MusicManager:isPlaying()
if (self:haveMusic()) then
return self.musics[1]:isPlaying( )
else
return false
end
end
function MusicManager:addMusic(filename, loop)
local music = love.audio.newSource(filename, "stream")
music:setLooping( loop )
table.insert(self.musics, music)
end
function MusicManager:silence()
if (self:haveMusic()) then
self.musics[1]:stop()
self.isPlaying = false
end
end
function MusicManager:skip()
if (self:haveMusic()) then
self.musics[1]:stop()
self.isPlaying = false
table.remove(self.musics, 1)
end
end
function MusicManager:purge()
if (self:haveMusic()) then
self.musics[1]:stop()
self.isPlaying = false
self.musics = {}
end
end
return MusicManager

View file

@ -21,32 +21,36 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]] ]]
local Serializer = require "birb.classes.serializable.serializer"
local OptionsManager = Object:extend() local OptionsManager = Serializer:extend()
local cwd = (...):gsub('%.options$', '') .. "."
local binser = require(cwd .. "modules.gamesystem.libs.binser")
local TRANSLATION_PATH = "datas/languages/" local TRANSLATION_PATH = "datas/languages/"
local OPTION_FILE = "options.data"
-- INIT FUNCTIONS -- INIT FUNCTIONS
-- Initialize and configure the game options -- Initialize and configure the game options
function OptionsManager:new(controller) function OptionsManager:new(controller)
OptionsManager.super.new(self, {"data"})
self.controller = controller self.controller = controller
-- We begin by creating an empty data table before reading the data. -- We begin by creating an empty data table before reading the data.
self.data = {} self:reset()
self:read() self:read()
end end
function OptionsManager:reset() function OptionsManager:reset()
local conf = self.controller:getDefaultConf()
-- Reset the option to the game defaults. -- Reset the option to the game defaults.
self.data = {}
self.data.video = {} self.data.video = {}
self.data.video.crtfilter = false self.data.video.crtfilter = (conf.window.crtfilter == true)
self.data.video.resolution = 2 self.data.video.resolution = conf.window.resolution or 1
self.data.video.border = true self.data.video.border = (conf.window.borderless == false)
self.data.video.vsync = true self.data.video.vsync = (conf.window.vsync ~= false)
self.data.video.fullscreen = false self.data.video.fullscreen = (conf.window.fullscreen == true)
-- We load the default files -- We load the default files
self.data.input = self:getInputDefaultData() self.data.input = self:getInputDefaultData()
@ -55,27 +59,13 @@ function OptionsManager:reset()
self.data.language = self:getTranslationDefaultData() self.data.language = self:getTranslationDefaultData()
self.data.audio = {} self.data.audio = {}
self.data.audio.music = 100 self.data.audio.music = conf.volume.music or 100
self.data.audio.sfx = 100 self.data.audio.sfx = conf.volume.sfx or 100
end end
-- INFO FUNCTIONS -- INFO FUNCTIONS
-- Get informations from the option managers -- Get informations from the option managers
function OptionsManager:getFile(absolute)
local dir = ""
if absolute then
dir = love.filesystem.getSaveDirectory() .. "/"
if not utils.filesystem.exists(dir) then
love.filesystem.createDirectory( "" )
end
end
local filepath = dir .. "options.data"
return filepath
end
function OptionsManager:getInputDefaultData() function OptionsManager:getInputDefaultData()
local _path = "datas/inputs.lua" local _path = "datas/inputs.lua"
local datas = {} local datas = {}
@ -142,30 +132,11 @@ end
-- FIXME: maybe subclass a special module for that ? -- FIXME: maybe subclass a special module for that ?
function OptionsManager:write() function OptionsManager:write()
local data = self:getData() self:serialize(OPTION_FILE)
local filepath = self:getFile(true)
binser.writeFile(filepath, data)
end end
function OptionsManager:read() function OptionsManager:read()
local filepath = self:getFile(true) self:deserialize(OPTION_FILE)
if utils.filesystem.exists("options.data") then
local loadedDatas = binser.readFile(filepath)
self.controller.debug:print("core/options", "data file found, loading it")
self:setData(loadedDatas[1])
else
self:reset()
self.controller.debug:print("core/options", "no data file found, reseting data")
end
end
function OptionsManager:getData(data)
return self.data
end
function OptionsManager:setData(data)
self.data = data
end end
return OptionsManager return OptionsManager

View file

@ -24,8 +24,7 @@
local ScreenManager = Object:extend() local ScreenManager = Object:extend()
local cwd = (...):gsub('%.screen$', '') .. "." local CScreen = require("birb.libs.cscreen")
local CScreen = require(cwd .. "libs.cscreen")
-- INIT FUNCTIONS -- INIT FUNCTIONS
-- Initialize and configure the screen manager -- Initialize and configure the screen manager

View file

@ -0,0 +1,52 @@
-- birb :: The main birb script, loading the core and main utilities
--[[
Copyright © 2021 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
birb = {}
-- GLOBAL UTILS/FUNCTION LOADING
-- Load in the global namespace utilities that'll need to be reusable everywhere
-- in the game
Object = require("birb.libs.classic")
utils = require("birb.utils")
enum = require("birb.utils.enum")
birb.Core = require("birb.core")
function birb.start(gamemodule)
birb.startCore()
if (gamemodule ~= nil) then
birb.startGame(gamemodule)
end
end
function birb.startCore()
core = birb.Core()
end
function birb.startGame(gamemodule)
local GameObject = require(gamemodule)
game = GameObject()
end
require("birb.callbacks")

View file

@ -24,7 +24,7 @@
local Assets = Object:extend() local Assets = Object:extend()
local cwd = (...):gsub('%.init$', '') .. "." local cwd = (...):gsub('%.init$', '') .. ".types."
local Texture = require(cwd .. "texture") local Texture = require(cwd .. "texture")
@ -167,28 +167,29 @@ function Assets:playSFX(filename)
end end
end end
function Assets:setMusic(filename) -- MUSIC FUNCTIONS
if filename ~= nil then -- All thse functions are deprecated, prefer core.music
if (self.music ~= nil) then
self.music:stop() function Assets:setMusic(filename, loop)
end core.debug:warning("assets", "Assets:setMusic is deprecated")
self.music = love.audio.newSource(filename, "stream" ) core.music:skip()
self.music:setVolume(core.options.data.audio.music / 100) core.music:addMusic(filename, (loop ~= false))
end core.music:playMusic()
end end
function Assets:silence() function Assets:silence()
love.audio.stop() core.debug:warning("assets", "Assets:silence is deprecated")
core.music:silence()
end end
function Assets:resetMusic() function Assets:resetMusic()
self.music = nil core.debug:warning("assets", "Assets:resetMusic is deprecated")
core.music:purge()
end end
function Assets:playMusic() function Assets:playMusic()
if not (self.music == nil) then core.debug:warning("assets", "Assets:playMusic is deprecated")
love.audio.play(self.music) core.music:playMusic()
end
end end
-- IMAGES FUNCTIONS -- IMAGES FUNCTIONS

View file

@ -124,10 +124,15 @@ end
-- CALLBACK FUNCTIONS -- CALLBACK FUNCTIONS
-- Handle getting a calback from the animation system -- Handle getting a calback from the animation system
function Animator:setCallback(actor) function Animator:setCallbackTarget(actor)
self.actor = actor self.actor = actor
end end
function Animator:setCallback(actor)
core.debug:warning("Animator", "Animator:setCallback is deprecated, prefer Animator:setCallbackTarget instead")
self:setCallbackTarget(actor)
end
function Animator:sendCallback() function Animator:sendCallback()
if (self.actor ~= nil) then if (self.actor ~= nil) then
self.actor:animationEnded(self.currentAnimation) self.actor:animationEnded(self.currentAnimation)

View file

@ -1,4 +1,4 @@
local TransitionParent = require "core.modules.transitions.parent" local TransitionParent = require "birb.modules.transitions.parent"
local CanvasTransition = TransitionParent:extend() local CanvasTransition = TransitionParent:extend()
function CanvasTransition:new(func, ox, oy, fadeOut, easeIn, easeOut, duration, wait) function CanvasTransition:new(func, ox, oy, fadeOut, easeIn, easeOut, duration, wait)

View file

@ -1,4 +1,4 @@
local TransitionParent = require "core.modules.transitions.canvas" local TransitionParent = require "birb.modules.transitions.canvas"
local DefaultTransition = TransitionParent:extend() local DefaultTransition = TransitionParent:extend()
function DefaultTransition:new(func, ox, oy, fadeOut) function DefaultTransition:new(func, ox, oy, fadeOut)

View file

@ -1,4 +1,4 @@
local TransitionParent = require "core.modules.transitions.canvas" local TransitionParent = require "birb.modules.transitions.canvas"
local DecalTransition = TransitionParent:extend() local DecalTransition = TransitionParent:extend()
function DecalTransition:new(func, ox, oy, fadeOut, decal) function DecalTransition:new(func, ox, oy, fadeOut, decal)

View file

@ -1,4 +1,4 @@
local TransitionParent = require "core.modules.transitions.parent" local TransitionParent = require "birb.modules.transitions.parent"
local DefaultTransition = TransitionParent:extend() local DefaultTransition = TransitionParent:extend()
function DefaultTransition:new(func, ox, oy, fadeOut) function DefaultTransition:new(func, ox, oy, fadeOut)

View file

@ -0,0 +1,4 @@
return {
default = require "birb.modules.transitions.default",
circle = require "birb.modules.transitions.circle"
}

View file

@ -1,5 +1,5 @@
local TransitionParent = Object:extend() local TransitionParent = Object:extend()
local TweenManager = require "game.modules.tweenmanager" local TweenManager = require "birb.classes.time"
function TransitionParent:new(func, ox, oy, fadeOut, easeIn, easeOut, duration, wait) function TransitionParent:new(func, ox, oy, fadeOut, easeIn, easeOut, duration, wait)
self.tween = TweenManager(self) self.tween = TweenManager(self)

View file

@ -21,19 +21,34 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]] ]]
local Rect = require "birb.classes.2D.rect"
local cwd = (...):gsub('%.actor2D$', '') .. "." local BaseActor = require "birb.modules.world.actors.mixins.base"
local BaseActor = require(cwd .. "baseactor") local SpritedActor = require("birb.modules.world.actors.mixins.sprites")
local Actor2D = BaseActor:extend() local TimedActor = require("birb.modules.world.actors.mixins.timers")
local InputActor = require("birb.modules.world.actors.mixins.inputs")
local PhysicalActor = require("birb.modules.world.actors.mixins.physics")
local Hitbox = require(cwd .. "utils.hitbox2D") local Actor2D = Rect:extend()
Actor2D:implement(BaseActor)
Actor2D:implement(SpritedActor)
Actor2D:implement(TimedActor)
Actor2D:implement(InputActor)
Actor2D:implement(PhysicalActor)
local Hitbox = require "birb.modules.world.actors.utils.hitbox2D"
-- INIT FUNCTIONS -- INIT FUNCTIONS
-- Initialise the actor and its base functions -- Initialise the actor and its base functions
function Actor2D:new(world, type, x, y, w, h, isSolid) function Actor2D:new(world, type, x, y, w, h, isSolid)
Actor2D.super.new(self, world, type, x, y, 0, w, h, 0, isSolid) Actor2D.super.new(self, x, y, w, h)
self:initHitboxes()
self:init(world, type)
self:initPhysics(Hitbox, isSolid)
self:initTimers()
self:initSprite()
self:initKeys()
end end
function Actor2D:destroy() function Actor2D:destroy()
@ -45,21 +60,10 @@ end
-- PHYSICS FUNCTIONS -- PHYSICS FUNCTIONS
-- Handle movement and collisions. -- Handle movement and collisions.
function Actor2D:autoMove(dt) function Actor2D:moveToFuturePosition(dt)
self:updateHitboxes()
self.onGround = false
self:applyGravity(dt)
local dx, dy = self:getFuturePosition(dt) local dx, dy = self:getFuturePosition(dt)
local newx, newy, cols, colNumber = self:move(dx, dy) local _, _, cols, colNumber = self:move(dx, dy)
return cols, colNumber
-- apply after the movement the friction, until the player stop
-- note: the friction is applied according to the delta time,
-- thus the friction should be how much speed is substracted in 1 second
self:solveAllCollisions(cols)
self:applyFriction(dt)
end end
function Actor2D:changeSpeedToCollisionNormal(normal) function Actor2D:changeSpeedToCollisionNormal(normal)
@ -80,16 +84,16 @@ end
function Actor2D:move(dx, dy) function Actor2D:move(dx, dy)
local cols, colNumber = {}, 0 local cols, colNumber = {}, 0
if (self.isDestroyed == false) then if (self.isDestroyed == false) then
self.x, self.y, cols, colNumber = self.mainHitbox:checkCollision(dx, dy, self.filter) self.x, self.y, cols, colNumber = self.mainHitbox:checkCollisionAtPoint(dx, dy, self.filter)
self.mainHitbox:updatePosition() self.mainHitbox:updatePosition()
end end
return self.x, self.y, cols, colNumber return self.x, self.y, cols, colNumber
end end
function Actor2D:checkCollision(dx, dy) function Actor2D:checkCollisionAtPoint(dx, dy)
local x, y, cols, colNumber = dx, dy, {}, 0 local x, y, cols, colNumber = dx, dy, {}, 0
if (self.isDestroyed == false) then if (self.isDestroyed == false) then
x, y, cols, colNumber = self.mainHitbox:checkCollision(dx, dy, self.filter) x, y, cols, colNumber = self.mainHitbox:checkCollisionAtPoint(dx, dy, self.filter)
end end
return self.x, self.y, cols, colNumber return self.x, self.y, cols, colNumber
end end
@ -107,7 +111,7 @@ end
function Actor2D:checkGround() function Actor2D:checkGround()
local dx, dy = self.x, self.y + utils.math.sign(self.grav) local dx, dy = self.x, self.y + utils.math.sign(self.grav)
local newx, newy, cols, colNumber = self:checkCollision(dx, dy) local newx, newy, cols, colNumber = self:checkCollisionAtPoint(dx, dy)
for i, col in ipairs(cols) do for i, col in ipairs(cols) do
if (col.type == "touch") or (col.type == "bounce") or (col.type == "slide") then if (col.type == "touch") or (col.type == "bounce") or (col.type == "slide") then
@ -129,74 +133,13 @@ end
-- HITBOXES FUNCTIONS -- HITBOXES FUNCTIONS
-- Functions related to actor hitboxes -- Functions related to actor hitboxes
function Actor2D:addHitboxFromFrameData(framedata, animationID, frameID, hitboxID) function Actor2D:packForHitbox()
local sx, sy = self:getSpriteScalling() return {0, 0, self.w, self.h}
local type = framedata[1]
local ox = framedata[2]
local oy = framedata[3]
local w = framedata[4]
local h = framedata[5]
local isSolid = framedata[6] or false
local anim = animationID or "null"
local frame = frameID or 0
local id = hitboxID or 0
if (sx < 0) then
ox = self.w - ox - w
end
if (sy < 0) then
oy = self.h - oy - h
end
if (type == "main") then
self.mainHitbox:modify(ox, oy, w, h)
else
local hitboxName = anim .. frame .. type .. id
self:addHitbox(hitboxName, type, ox, oy, w, h, isSolid)
return hitboxName
end
end
function Actor2D:initMainHitbox()
self.mainHitbox = Hitbox(self, self.type, 0, 0, self.w, self.h, self.isSolid)
self.mainHitbox:advertiseAsMainHitbox()
end
function Actor2D:addHitbox(name, type, ox, oy, w, h, isSolid)
if (self.hitboxes[name] ~= nil) then
core.debug:warning("actor2D", "the hitbox " .. name .. " already exists")
else
local hitbox = Hitbox(self, type, ox, oy, w, h, isSolid)
self.hitboxes[name] = hitbox
return hitbox
end
end
function Actor2D:checkHitboxCollisions(name, filter)
self:checkHitboxCollisionsAtPoint(name, self.x, self.y, filter)
end
function Actor2D:checkHitboxCollisionsAtPoint(name, dx, dy, filter)
local x, y, cols, colNumber = dx, dy, {}, 0
local filter = filter or self.filter
if (self.isDestroyed == false) and (self.hitboxes[name] ~= nil) then
x, y, cols, colNumber = self.hitboxes[name]:checkCollision(dx, dy, filter)
local type = self.hitboxes[name].type
for i, col in ipairs(cols) do
self:hitboxResponse(name, type, col)
end
end
return x, y, cols, colNumber
end end
-- DRAW FUNCTIONS -- DRAW FUNCTIONS
-- Draw the actors. -- Draw the actors.
function Actor2D:getShape()
return (self.x), (self.y), self.w, (self.h)
end
function Actor2D:draw() function Actor2D:draw()
self:drawStart() self:drawStart()
local x, y = math.floor(self.x), math.floor(self.y) local x, y = math.floor(self.x), math.floor(self.y)

View file

@ -0,0 +1,177 @@
-- actor3D.lua :: the implementation of a 2D actor. It contain every element
-- needed to create your own 2D actors.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local Hitbox = require("birb.modules.world.actors.utils.hitbox3D")
local Boxes = require("birb.modules.world.actors.utils.boxes")
local BasicBox = require "birb.classes.3D.box"
local BaseActor = require("birb.modules.world.actors.mixins.base")
local SpritedActor = require("birb.modules.world.actors.mixins.sprites")
local TimedActor = require("birb.modules.world.actors.mixins.timers")
local InputActor = require("birb.modules.world.actors.mixins.inputs")
local PhysicalActor = require("birb.modules.world.actors.mixins.physics")
local Shape3DActor = require("birb.modules.world.actors.mixins.shapes")
local Actor3D = BasicBox:extend()
Actor3D:implement(BaseActor)
Actor3D:implement(SpritedActor)
Actor3D:implement(TimedActor)
Actor3D:implement(InputActor)
Actor3D:implement(PhysicalActor)
Actor3D:implement(Shape3DActor)
-- INIT FUNCTIONS
-- Initialise the actor and its base functions
function Actor3D:new(world, type, x, y, z, w, h, d, isSolid)
Actor3D.super.new(self, x, y, z, w, h, d)
self:init(world, type)
self:initPhysics(Hitbox, isSolid)
self:initTimers()
self:initSprite()
self:initKeys()
self:initShape(Boxes, true)
end
function Actor3D:destroy()
self:destroyShape()
self.mainHitbox:destroy()
self.world:removeActor(self)
self.isDestroyed = true
end
-- PHYSICS FUNCTIONS
-- Handle movement and collisions.
function Actor3D:moveToFuturePosition(dt)
local dx, dy, dz = self:getFuturePosition(dt)
local _, _, _, cols, colNumber = self:move(dx, dy, dz)
return cols, colNumber
end
function Actor3D:changeSpeedToCollisionNormal(normal)
local xsp, ysp, zsp = self.xsp, self.ysp, self.zsp
local nx, ny, nz = normal.x, normal.y, normal.z
if (nx < 0 and xsp > 0) or (nx > 0 and xsp < 0) then
xsp = -xsp * self.bounceFactor
end
if (ny < 0 and ysp > 0) or (ny > 0 and ysp < 0) then
ysp = -ysp * self.bounceFactor
end
if (nz < 0 and zsp > 0) or (nz > 0 and zsp < 0) then
zsp = -zsp * self.bounceFactor
end
self.xsp, self.ysp, self.zsp = xsp, ysp, zsp
end
function Actor3D:move(dx, dy, dz)
local cols, colNumber = {}, 0
local oldx, oldy, oldz = self.x, self.y, self.z
if (self.isDestroyed == false) then
self.x, self.y, self.z, cols, colNumber = self.mainHitbox:checkCollisionAtPoint(dx, dy, dz, self.filter)
self.mainHitbox:updatePosition()
self.world:updateShape(self)
end
if (oldx ~= self.x) or (oldy ~= self.y) or (oldz ~= self.z) or (self.shadowTargetsPrevious == nil) then
if (self.doCastShadows) then
self:castShadow()
end
end
return self.x, self.y, self.z, cols, colNumber
end
function Actor3D:checkCollisionAtPoint(dx, dy, dz)
local x, y, z, cols, colNumber = dx, dy, dz, {}, 0
if (self.isDestroyed == false) then
x, y, z, cols, colNumber = self.mainHitbox:checkCollisionAtPoint(dx, dy, dz, self.filter)
end
return self.x, self.y, self.z, cols, colNumber
end
-- GRAVITY SYSTEM FUNCTIONS
-- All functions related to gravity
function Actor3D:applyGravity(dt)
local grav = self.grav * -1
self.zsp = self.zsp + (grav * dt)
if utils.math.sign(self.zsp) == utils.math.sign(grav) then
self:checkGround( )
end
end
function Actor3D:checkGround()
local dx, dy, dz = self.x, self.y, self.z - utils.math.sign(self.grav)
local newx, newy, newz, cols, colNumber = self:checkCollisionAtPoint(dx, dy, dz)
for i, col in ipairs(cols) do
if (col.type == "touch") or (col.type == "bounce") or (col.type == "slide") then
if not (self.grav == 0) then
if col.normal.z == utils.math.sign(self.grav) then self.onGround = true end
end
end
end
end
-- COORDINATE/MOVEMENT FUNCTIONS
-- Handle coordinate
function Actor3D:getViewCenter()
local x, y, z = self:getCenter()
return x, y - (self.d/2)
end
-- HITBOXES FUNCTIONS
-- Functions related to actor hitboxes
function Actor3D:packForHitbox()
return {0, 0, 0, self.w, self.h, self.d}
end
-- DRAW FUNCTIONS
-- Draw the actors.
function Actor3D:drawShadow(x, y)
love.graphics.setColor(0, 0, 0, 1)
love.graphics.rectangle("fill", x, y, self.w, self.h)
utils.graphics.resetColor()
end
function Actor3D:draw()
self:drawStart()
if (self.box ~= nil) then
self.box:draw(self.x, self.y, self.z)
else
local x, y = math.floor(self.x), math.floor(self.y - self.z - self.d + (self.h/2))
self:drawSprite(x, y)
end
self:drawEnd()
end
return Actor3D

View file

@ -29,8 +29,7 @@ function GFX:new(world, x, y, spritename)
local width, height = world.scene.assets.sprites[spritename]:getDimensions() local width, height = world.scene.assets.sprites[spritename]:getDimensions()
GFX.super.new(self, world, "gfx", x - (width/2), y - (height/2), width, height) GFX.super.new(self, world, "gfx", x - (width/2), y - (height/2), width, height)
self:setSprite(spritename) self:setSprite(spritename, true)
self:cloneSprite()
end end
function GFX:animationEnded(animation) function GFX:animationEnded(animation)

View file

@ -29,8 +29,7 @@ function GFX:new(world, x, y, z, spritename)
local width, height = world.scene.assets.sprites[spritename]:getDimensions() local width, height = world.scene.assets.sprites[spritename]:getDimensions()
GFX.super.new(self, world, "gfx", x - (width/2), y - (width/2), z - (height/2), width, width, height) GFX.super.new(self, world, "gfx", x - (width/2), y - (width/2), z - (height/2), width, width, height)
self:setSprite(spritename) self:setSprite(spritename, true)
self:cloneSprite()
end end
function GFX:animationEnded(animation) function GFX:animationEnded(animation)

View file

@ -0,0 +1,118 @@
-- BaseActor.lua :: the global implementation of an actor. Basically, it abstract
-- everything that isn't only 2D or 3D related to the actor system.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local BaseActor = Object:extend()
-- INIT FUNCTIONS
-- Initialise the actor and its base functions
function BaseActor:init(world, type)
self.type = type or ""
self.depth = 0
self.updateFunctions = {}
self:setManagers(world)
self:setDebugColor(1, 1, 1)
self:register()
self.useTileCollision = true
end
function BaseActor:setProperties(properties)
-- Do something here
end
function BaseActor:addUpdateFunction(func)
table.insert(self.updateFunctions, func)
end
function BaseActor:applyUpdateFunctions(dt)
for key, func in ipairs(self.updateFunctions) do
func(self, dt)
end
end
function BaseActor:setManagers(world)
self.world = world
self.scene = world.scene
self.obj = world.obj
self.assets = self.scene.assets
end
function BaseActor:setDebugColor(r,g,b)
self.debug = {}
self.debug.r = r
self.debug.g = g
self.debug.b = b
end
function BaseActor:register()
self.world:registerActor(self)
self.isDestroyed = false
end
function BaseActor:destroy()
self.world:removeActor(self)
self.isDestroyed = true
end
-- UPDATE FUNCTIONS
-- Theses functions are activated every steps
function BaseActor:updateStart(dt)
end
function BaseActor:update(dt)
self:updateStart(dt)
self:applyUpdateFunctions(dt)
self:updateEnd(dt)
end
function BaseActor:updateEnd(dt)
end
-- DRAW FUNCTIONS
-- Draw the actors.
function BaseActor:drawStart()
end
function BaseActor:draw()
self:drawStart()
self:drawEnd()
end
function BaseActor:drawEnd()
end
function BaseActor:drawHUD(id, height, width)
end
return BaseActor

View file

@ -0,0 +1,34 @@
-- InputActor.lua :: Get input from the world object.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local InputActor = Object:extend()
function InputActor:initKeys()
self.keys = core.input.fakekeys
end
function InputActor:getInput(keys)
self.keys = keys or core.input.fakekeys
end
return InputActor

View file

@ -0,0 +1,273 @@
PhysicalActor = Object:extend()
-- PHYSICS FUNCTIONS
-- Raw implementation of everything common in physics
function PhysicalActor:initPhysics(hitboxObj, isSolid)
self.isSolid = isSolid or false
self.xsp = 0
self.ysp = 0
self.zsp = 0
self.xfrc = 0
self.yfrc = 0
self.zfrc = 0
self:initGravity()
self:initHitboxes(hitboxObj)
self:setBounceFactor()
self:setFilter()
self:addUpdateFunction(self.autoMove)
end
function PhysicalActor:setBounceFactor(newBounceFactor)
self.bounceFactor = newBounceFactor or 0
end
function PhysicalActor:setFilter()
-- Init the bump filter
self.filter = function(item, other)
if (other.owner == self) then
-- ignore every collision with our own hitboxes
return nil
elseif (other.isSolid) then
return "slide"
else
return "cross"
end
end
end
function PhysicalActor:getFuturePosition(dt)
local dx, dy, dz
dx = self.x + self.xsp * dt
dy = self.y + self.ysp * dt
if (self.z ~= nil) then
dz = self.z + self.zsp * dt
end
return dx, dy, dz
end
function PhysicalActor:applyFriction(dt)
self.xsp = utils.math.toZero(self.xsp, self.xfrc * dt)
self.ysp = utils.math.toZero(self.ysp, self.yfrc * dt)
if (self.z ~= nil) then
self.zsp = utils.math.toZero(self.zsp, self.zfrc * dt)
end
end
function PhysicalActor:solveAllCollisions(cols)
for i, col in ipairs(cols) do
self:collisionResponse(col)
if (col.type == "touch") or (col.type == "bounce") or (col.type == "slide") then
self:changeSpeedToCollisionNormal(col.normal)
end
end
end
function PhysicalActor:collisionResponse(collision)
-- here come the response to the collision
end
function PhysicalActor:changeSpeedToCollisionNormal(normal)
-- Empty function in PhysicalActor
end
-- COORDINATE/MOVEMENT FUNCTIONS
-- Handle coordinate
-- Will be replaced by functions inside Actors or Rects/Point
function PhysicalActor:getViewCenter()
return self:getCenter()
end
-- GRAVITY SYSTEM FUNCTIONS
-- All functions related to gravity
function PhysicalActor:initGravity()
if (self.world.gravity.isDefault) then
self.grav = self.world.gravity.grav
else
self.grav = 0
end
self.onGround = false
end
function PhysicalActor:setGravity(grav)
-- It's basically now a function with two roles at once :
-- - activate the gravity
-- - use the gravity value the dev want
self.grav = grav or self.world.gravity.grav
end
function PhysicalActor:applyGravity(dt)
-- Empty function in PhysicalActor
end
function PhysicalActor:checkGround()
-- Empty function in PhysicalActor
end
function PhysicalActor:autoMove(dt)
self:updateHitboxes()
self.onGround = false
self:applyGravity(dt)
local cols, colNumber = self:moveToFuturePosition(dt)
-- apply after the movement the friction, until the player stop
-- note: the friction is applied according to the delta time,
-- thus the friction should be how much speed is substracted in 1 second
self:solveAllCollisions(cols)
self:applyFriction(dt)
end
-- HITBOX FUNCTIONS
-- All functions to handle hitboxes
function PhysicalActor:initHitboxes(hitboxObj)
self.Hitbox = hitboxObj
self:initMainHitbox()
self.hitboxes = {}
self.hitboxListFile = ""
self.hitboxList = nil
end
function PhysicalActor:initMainHitbox()
self.mainHitbox = self.Hitbox(self, self.type, self:packForHitbox(), 0, 0, self.isSolid)
self.mainHitbox:advertiseAsMainHitbox()
end
function PhysicalActor:setHitboxFile(file)
self.hitboxList = require(file)
self.hitboxListFile = file
end
function PhysicalActor:getAutomaticHitboxLoading()
return (self.hitboxList ~= nil)
end
function PhysicalActor:getHitboxFile()
return self.hitboxListFile
end
function PhysicalActor:getHitboxList(animation, frame)
if (animation == nil) or (self.hitboxList == nil) then
return self.hitboxList
else
local list = self.hitboxList[animation]
if (frame == nil) or (list == nil) then
return list
else
return list[frame]
end
end
end
function PhysicalActor:addHitboxFromFrameData(framedata, animationID, frameID, hitboxID)
local sx, sy = self.sprite:getScalling()
local type = framedata[1]
local box = framedata[2]
local isSolid = framedata[3] or false
local anim = animationID or "null"
local frame = frameID or 0
local id = hitboxID or 0
if (type == "main") then
self.mainHitbox:setFromData(box, sx, sy)
else
local hitboxName = anim .. frame .. type .. id
self:addHitbox(hitboxName, type, box, sx, sy, isSolid)
return hitboxName
end
end
function PhysicalActor:addHitbox(name, type, data, sx, sy, isSolid)
if (self.hitboxes[name] ~= nil) then
core.debug:logWarn("PhysicalActor", "the hitbox " .. name .. " already exists")
else
local hitbox = self.Hitbox(self, type, data, sx, sy, isSolid)
self.hitboxes[name] = hitbox
return hitbox
end
end
function PhysicalActor:updateHitboxes()
if (self.hitboxList ~= nil) then
self:purgeHitbox()
local animation, frame
animation = self.sprite:getCurrentAnimation()
frame = self.sprite:getRelativeFrame()
local hitboxList = self:getHitboxList(animation, frame)
if (hitboxList ~= nil) then
for i, v in ipairs(hitboxList) do
self:addHitboxFromFrameData(v, animation, frame, i)
end
end
end
end
function PhysicalActor:applyHitboxesCollisions(filter)
for k, v in pairs(self.hitboxes) do
self:applyHitboxCollisions(k, filter)
end
end
function PhysicalActor:applyHitboxCollisions(name, filter)
local cols, colNumber = {}, 0
local filter = filter or self.filter
if (self.isDestroyed == false) and (self.hitboxes[name] ~= nil) then
cols, colNumber = self.hitboxes[name]:checkCollision(filter)
local type = self.hitboxes[name].type
for i, col in ipairs(cols) do
self:hitboxResponse(name, type, col)
end
end
return cols, colNumber
end
function PhysicalActor:hitboxResponse(name, type, collision)
-- just a blank placeholder function
end
function PhysicalActor:removeHitbox(name)
if (self.hitboxes[name] ~= nil) then
self.hitboxes[name]:destroy()
self.hitboxes[name] = nil
end
end
function PhysicalActor:purgeHitbox()
for k, v in pairs(self.hitboxes) do
v:destroy()
end
self.hitboxes = {}
end
function PhysicalActor:drawHitboxes()
for k, v in pairs(self.hitboxes) do
v:draw()
end
self:drawMainHitbox()
end
function PhysicalActor:drawMainHitbox()
if (self.mainHitbox ~= nil) then
self.mainHitbox:draw()
end
end
return PhysicalActor

View file

@ -0,0 +1,97 @@
-- ShapedActor.lua :: Handle the shape of a 2.5D actor.
-- It handle terrain box, and shadows
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local ShapedActor = Object:extend()
function ShapedActor:initShape(boxObj, doCastShadows)
self.world:registerShape(self)
self.boxes = boxObj
self.doCastShadows = doCastShadows
end
function ShapedActor:destroyShape()
self:removeOldShadowTargets()
if self.box ~= nil then
self.world:removeTerrain(self)
end
self.world:removeShape(self)
end
-- SHADOW FUNCTIONS
-- Handle everything related to shadow
function ShapedActor:castShadow()
local shadowTargets = self.world:getTerrainInRect(self.x, self.y, self.w, self.d)
-- initialize the shadowTargetsPrevious variable if it doesn't exist
if (self.shadowTargetsPrevious == nil) then
self.shadowTargetsPrevious = {}
end
for i, target in ipairs(shadowTargets) do
-- We test if the actor is below the current actor
if (target ~= self) and (target.box ~= nil) then
if (target.z + target.d <= self.z + self.d) then
-- Remove the target of the list of item targeted last update,
-- in order to only have object no longer shadowed after the
-- end of the loop
for j, oldtarget in ipairs(self.shadowTargetsPrevious) do
if (target == oldtarget) then
table.remove(self.shadowTargetsPrevious, j)
end
end
-- We update the shadow source
local x, y = math.floor(self.x - target.x), math.floor(self.y - target.y)
target.box:setShadowSource(self, x, y)
end
end
end
-- At this point, if a target is still in the shadowTargetsPrevious list,
-- it mean that it's not shadowed. So we can simply remove the shadow.
self:removeOldShadowTargets()
self.shadowTargetsPrevious = shadowTargets
end
function ShapedActor:removeOldShadowTargets()
if (self.shadowTargetsPrevious ~= nil) then
for i, target in ipairs(self.shadowTargetsPrevious) do
if (target.box ~= nil) then
target.box:removeShadowSource(self)
end
end
end
end
function ShapedActor:redrawShadowCanvas()
if (self.box ~= nil) then
self.box:redrawShadowCanvas()
end
end
return ShapedActor

View file

@ -0,0 +1,101 @@
-- SpritedActor.lua :: Handle the sprite of the actor.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local SpritedActor = Object:extend()
local Sprite = require("birb.modules.world.actors.utils.sprites")
function SpritedActor:initSprite()
self:addUpdateFunction(self.updateSprite)
end
function SpritedActor:setSprite(spritename, isClone, ox, oy)
self.sprite = Sprite(self, spritename, ox, oy)
if (isClone) then
self.sprite:clone()
end
end
function SpritedActor:changeAnimation(animation, restart)
if (self.sprite ~= nil) then
core.debug:warning("actor", "the function SpritedActor:changeAnimation is deprecated, prefer SpritedActor.sprite:changeAnimation()")
self.sprite:changeAnimation(animation, restart)
end
end
function SpritedActor:animationEnded(animation)
-- Empty placeholder function
end
function SpritedActor:setCustomSpeed(customSpeed)
if (self.sprite ~= nil) then
core.debug:warning("actor", "the function SpritedActor:setCustomSpeed is deprecated, prefer SpritedActor.sprite:setCustomSpeed()")
self.sprite:setCustomSpeed(customSpeed)
end
end
function SpritedActor:updateSprite(dt)
if (self.sprite ~= nil) then
self.sprite:update(dt)
end
end
function SpritedActor:getCurrentAnimation()
if (self.sprite ~= nil) then
core.debug:warning("actor", "the function SpritedActor:getCurrentAnimation is deprecated, prefer SpritedActor.sprite:getCurrentAnimation()")
return self.sprite:getCurrentAnimation()
end
end
function SpritedActor:getSpriteScalling()
core.debug:warning("actor", "the function SpritedActor:getSpriteScalling is deprecated, prefer SpritedActor.sprite:getScalling()")
return self.sprite:getScalling()
end
function SpritedActor:getFrame()
if (self.sprite ~= nil) then
core.debug:warning("actor", "the function SpritedActor:getFrame is deprecated, prefer SpritedActor.sprite:getFrame()")
return self.sprite:getFrame()
end
end
function SpritedActor:getRelativeFrame()
if (self.sprite ~= nil) then
core.debug:warning("actor", "the function SpritedActor:getRelativeFrame is deprecated, prefer SpritedActor.sprite:getRelativeFrame()")
return self.sprite:getRelativeFrame()
end
end
function SpritedActor:getAnimationDuration()
if (self.sprite ~= nil) then
core.debug:warning("actor", "the function SpritedActor:getAnimationDuration is deprecated, prefer SpritedActor.sprite:getAnimationDuration()")
return self.sprite:getAnimationDuration()
end
end
function SpritedActor:drawSprite(x, y, r, sx, sy, ox, oy, kx, ky)
if (self.sprite ~= nil) then
self.sprite:draw(x, y, r, sx, sy, ox, oy, kx, ky)
end
end
return SpritedActor

View file

@ -0,0 +1,49 @@
-- TimedActor.lua :: Handle the sprite of the actor.
--[[
Copyright © 2019 Kazhnuz
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
]]
local TimedActor = Object:extend()
local TweenManager = require "birb.classes.time"
-- TIMER FUNCTIONS
-- Control the integrated timers of the actor
function TimedActor:initTimers()
self.timers = TweenManager(self)
self:addUpdateFunction(self.updateTimers)
end
function TimedActor:addTimer(name, t)
core.debug:warning("actor", "function actor:addTimer is deprecated, prefer actor.timers:newTimer")
self.timers:newTimer(t, name)
end
function TimedActor:updateTimers(dt)
self.timers:update(dt)
end
function TimedActor:timerResponse(name)
-- here come the timer responses
end
return TimedActor

Some files were not shown because too many files have changed in this diff Show more