ObjectProperties
Introduction
Pour customiser vos véhicules, ajouter une clé, une plaque d'immatriculation, ou encore une radio, vous devrez ajouter leur ajouter ce qu'on appelle des propriétés à vos objets. Voici comment-faire.
Tip
Il est fortement conseillé de lire l'introduction à la création de packs pour comprendre comment le loader de DynamX fonctionne.
Ajout de propriétés à des objets (véhicules, roues...)
Ajouter votre classe contenant les propriétés customs
Danger
Cette partie n'est pas à jour pour la 4.0.0. Elle le sera prochainement.
Ces propriétés sont regroupées dans les SubInfoType
et sont chargées en lisant les fichiers de configuration des différents objets (véhicules, moteurs, roues...).
Vous devez créer une classe implémentant ISubInfoType<T>
où T est le type d'objet possédant les nouvelles propriétés (Voir plus bas pour en voir la liste).
Votre IDE préféré vous demandera ensuite d'implémenter la fonction appendTo(T owner)
qui devra ajouter les propriétés à l'objet (en général owner.addSubProperty(this)
).
Pour enregistrer votre SubInfoType
, vous devrez utiliser le SubInfoTypesRegistry
, voici un exemple d'utilisation :
DynamXObjectLoaders.WHEELED_VEHICLES.getSubInfoTypesRegistry().addSubInfoType(new SubInfoTypeEntry<>("wheel", PartWheel::new, false));
DynamXObjectLoaders.WHEELED_VEHICLES
est le loader des véhicules, auquel on ajoute le loader des roues. Plein d'autres loaders sont disponibles dans la classe DynamXObjectLoaders
, à vous de voir ce qu'il vous faut. Seuls les loaders "ITEMS" et "SOUNDS" n'acceptent pas les SubInfoType
.
Le paramètre "true" du SubInfoTypeEntry
permet d'accepter n'importe quel nom dans le fichier de config, tant qu'il commence par "wheel" : ce qui correspond à ce code de config :
WheelFrontLeft{
//Propriétés à mettre ici
}
Tip
Sachez qu'il est possible de créer son propre registre, les objets doivent implémenter ISubInfoTypeOwner.
Ajouter les propriétés dans votre classe
Vous pourrez ajouter toutes les fields que vous voulez dans votre classe, et vous devez toutes les annoter avec l'annotation @PackFileProperty
. Voici un exemple :
@PackFileProperty(configNames = "RotationPoint", required = false, type = DefinitionType.DynamXDefinitionTypes.VECTOR3F_INVERSED_Y)
private Vector3f rotationPoint;
Et une explication :
Variable | Description |
---|---|
configNames | Nom de la proprité dans le fichier de config |
required | Facultatif, et vaut true par défaut. Marque la propriété comme requise et affiche une erreur si elle n'est pas renseignée |
type | Facultatif, le type est détecté automatiquement sauf pour les Vector3f. La liste des types est disponible dans DynamXDefinitionTypes |
D'autres propriétés existent, à voir dans le code et la javadoc.
Il y a d'autres possibilités avec le loader de DynamX, à découvrir par vous-mêmes.
Utiliser ces propriétés dans des évènements
Tous les évènements sont appelés dans le l'event bus de forge.
Ils sont appelés sur différentes “sides” : les events “server side” sont toujours appelés côté serveur, les events “client side” sont toujours appelés côté client. Les events “simulation side” sont appelés côté serveur si on est en solo, et côté serveur ET client quand on est en multijoueur, les events “simulation thread side” sont sur les même sides mais peuvent être appelés dans un thread différent de celui principal.
En voici la liste :
Nom | Side | Description | Cancellable |
---|---|---|---|
ContentPackSystemEvent.ContentPackLoadEvent | Common | Appelé avant (phase PRE) et après (phase POST) le (re)chargement des packs. | Non |
PhysicsEvent.PhysicsEntityAddedEvent | Simulation thread | Appelé quand une entité a été ajoutée au monde physique. | Non |
PhysicsEvent.PhysicsEntityRemovedEvent | Simulation thread | Appelé quand une entité a été retirée du monde physique. | Non |
PhysicsEvent.StepSimulationEvent | Simulation thread | Appelé à chaque mise à jour du monde physique, à chaque tick du jeu. | Non |
PhysicsEvent.PhysicsWorldLoad | Simulation | Appelé quand le monde physique est créé, quand un monde Minecraft est créé. | Non |
PhysicsEvent.ChunkCollisionsStateEvent | Simulation thread | Appelé quand l’état des collisions d’un chunk a changé, permet par exemple d’ajouter/retirer des collisions à un chunk. | Non |
VehicleEntityEvent.VehicleInteractEntityEvent | Server | Appelé quand un joueur interagit avec un élément d’un véhicule. | Oui |
PhysicsEntityEvent.AttackedEvent | Server | Appelé quand une entité physique (voiture, prop) subit des dégâts de la part d’un joueur. Si l’event n’est pas annulé et que le joueur a un item pour détruire l’entité, elle l’est immédiatement. | Oui |
VehicleEntityEvent.MountVehicleEntityEvent | Common | Appelé quand un joueur a monté sur un siège. | Non |
VehicleEntityEvent.DismountVehicleEntityEvent | Common | Appelé quand un joueur est descendu d’un siège. | Non |
PhysicsEntityEvent.PhysicsEntityUpdateEvent | Common et Simulation thread | Appelé à chaque update d’une entité physique.Il y a deux types d’update : l’update dans le thread de minecraft : PhysicsEntityUpdateType.POST_ENTITY_UPDATE et l’update dans le thread physique : PhysicsEntityUpdateType.POST_PHYSICS_UPDATE. ServerPhysicsEntityUpdateEvent: Variante côté serveur. ClientPhysicsEntityUpdateEvent: Variante côté client. |
Non |
PhysicsEntityEvent.PhysicsEntityInitEvent | Common | Appelé après l’initialisation d’une entité physique (informations du pack, et physique si elle est activée sur cette side) | Non |
VehicleEntityEvent.SaveVehicleEntityNBT | Server | Appelé quand un véhicule est sauvegardé. | Non |
VehicleEntityEvent.LoadVehicleEntityNBT | Server | Appelé quand un véhicule est chargé. | Non |
VehicleEntityEvent.RenderCarEntityEvent | Client | Appelé quand une voiture est rendue, avant et après le rendu pour le chassis, les roues, les parts et les particules. Appelé après le rendu du debug d’une voiture (phase POST). | Oui |
VehicleEntityEvent.DrawVehicleEntityHUD OUTDATED | Client | Appelé quand le HUD d’un véhicule est rendu. | Oui |
VehicleEntityEvent.UpdateVehicleSoundEntityEvent | Client | Appelé quand les sons du moteur d’un véhicule sont mis à jour. | Oui |
Modules TODO |
Utiliser ces propriétés dans des entités : système de modules
Il y a deux types d’entités dans DynamX : les véhicules et les props.
Les véhicules, héritant de ModularPhysicsEntity
, fonctionnent de manière modulaire : pour l’instant, 3 types de modules sont implémentés, mais il est facile d’ajouter les siens. La classe de l’entité doit implémenter IHave<NomDuModule>
et ajouter ses modules dans la fonction createModules
, voir CarEntity
ou TrailerEntity
pour des exemples. Pour modifier les modules d’une entité, vous pouvez utiliser l’event CreateVehicleModulesEvent
. Les modules doivent implémenter l’interface IPhysicsModule
, qui fournit des fonctions appelées pas ModularPhysicsEntity
. Certains modules ont en plus une autre interface à implémenter, voir plus bas. Les modules touchant à la physique devront aussi posséder un “PhysicsHandler
” qui fera le lien avec le moteur de physique, ce PhysicsHandler
ne peut être créé que si le client (ou le serveur) simule la physique lui-même (pas le cas en solo par exemple), dans la fonction initPhysicsEntity
du module.
Modules implémentés dans le mod
Ces modules de base peuvent être ajoutés à n’importe quelle ModularPhysicsEntity
, leur synchronisation est automatiquement gérée par le système de sync du mod. Vous pouvez ajouter votre propre implémentation, mais il faut se référer à la javadoc pour voir ce qui est sync automatiquement grâce aux interfaces.
-> ISeatsModule
- Implémentation :
SeatsModule
- Ajout à une entité : implémenterIHaveSeats
- Ce module gère tout ce qui touche aux sièges, toutes les fonctions présentes dans
ISeatsModule
sont appelées par leModularPhysicsEntity
.
-> IPropulsionModule
- Ajout à une entité : implémenter
IHavePropulsion
- Ce module gère le moyen de propulsion : ce peut être des roues, des hélices…- Implémentations :
WheelsModule
: Ce module gère les roues. - Implémentation physique :IPropulsionHandler
(exemple :WheelsPhysicsHandler
). Les fonctions de contrôle de cette interface (accélération, frein…) sont appelées par l’EngineModule
, si il y en a un (les remorques n’en ont pas).
-> IEngineModule
- Implémentation :
EngineModule
- Ajout à une entité : implémenter
IHaveEngine
- Ce module gère tout ce qui touche au moteur (contrôles principalement), que ce soit un moteur de voiture ou d’avion… Ce module doit être ajouté après le module de propulsion dont il a besoin. Il gère également les contrôles du joueur.
- Implémentation physique :
IEnginePhysicsHandler
(voirEnginePhysicsHandler
pour un exemple)
D'autres exemples sont fournis dans les addons...
Utiliser le système de synchronisation
On entre dans une partie plus complexe... La synchronisation des entités est faite par UDP, à l'aide des SynchronizedVariables
, plus d'informations dans la javadoc.
Pour enregistrer ces variables, il faut utiliser SynchronizedVariablesRegistry.addSyncVar(location, callable, context)
où :
- location est une
ResourceLocation
unique pour cette variable - callable est une
Callable
retournant une nouvelle instance de la variable (typiquementMyVar::new
si le constructeur est vide) - context est une fonction indiquant si la variable doit être synchronisée à partir de la side donnée, avec le SimulationHolder donné (
PhysicsEntityNetHandler.getSimulationHolder()
), il est très important de bien réfléchir à cette fonction, voir les exemples du mod
To be continued