Tutorial available in the GitHub wiki
For some blocks or entities, an screen is necessary for the user to interact with it. For example a NPC could have a trade menu or a furnace a dialog where you can put materials in and out fo the furnace. The core module already contains such a dialog already: a default dialog for viewing chests.
As user you expect these interaction screens to have certain properties: For example you would except that the interaction dialog closes, when the interaction target gets out of reach. Vice versa you would except that the closing of the interaction dialog will terminate the interaction.
So I started working on a way to create a generic way of making interactions.
This patch series allows you to make Terasology to open an interaction dialog automatically when you press E, by just adding a simple component to an entity which should offer an interaction screen:
The first component specifies that an interaction can be started with E with the entity. The second component allows you to link an user interface to the interaction. It gets opened automatically when the transaction starts and when you close it the interaction will automatically terminated for you.
Because of network delay, there can be a difference between the request to start an interaction on the client and the confirmation of the server that the interaction is valid. To provide the user with an responsive UI, the clients predicts the start of the interaction and shows the UI instantly. This predicted start of an interaction gets signaled with an InteractionStartPredicted event which gets sent to the target entity. Likewise there is an InteractionEndPredicted event when the client predicts an interaction end.
For interaction screens it is important to know with which object the character is interacting with. The predicted interaction target can be obtained from the character via a predictedInteractionTarget field in the CharacterComponent. The character can be obtained from the local player which can be obtained via dependency injection. For an example have a look at the ContainerScreen class (on a branch with my patches):
For user actions that get validated by the authority (server), there is a authorizedInteractionTarget field in the CharacterComponent which describes the confirmed interaction status of the character. Confirming actions on the server is important to prevent cheating. Otherwise a cheater may fake the button press on an interaction screen even when he isn't even close enough for an interaction.
For some blocks or entities, an screen is necessary for the user to interact with it. For example a NPC could have a trade menu or a furnace a dialog where you can put materials in and out fo the furnace. The core module already contains such a dialog already: a default dialog for viewing chests.
As user you expect these interaction screens to have certain properties: For example you would except that the interaction dialog closes, when the interaction target gets out of reach. Vice versa you would except that the closing of the interaction dialog will terminate the interaction.
So I started working on a way to create a generic way of making interactions.
This patch series allows you to make Terasology to open an interaction dialog automatically when you press E, by just adding a simple component to an entity which should offer an interaction screen:
Code:
"InteractionTarget": {},
"InteractionScreen": {
"screen": "engine:containerScreen"
},
Because of network delay, there can be a difference between the request to start an interaction on the client and the confirmation of the server that the interaction is valid. To provide the user with an responsive UI, the clients predicts the start of the interaction and shows the UI instantly. This predicted start of an interaction gets signaled with an InteractionStartPredicted event which gets sent to the target entity. Likewise there is an InteractionEndPredicted event when the client predicts an interaction end.
For interaction screens it is important to know with which object the character is interacting with. The predicted interaction target can be obtained from the character via a predictedInteractionTarget field in the CharacterComponent. The character can be obtained from the local player which can be obtained via dependency injection. For an example have a look at the ContainerScreen class (on a branch with my patches):
Code:
@In
private LocalPlayer localPlayer;
// ...
containerInventory.bindTargetEntity(new ReadOnlyBinding<EntityRef>() {
@Override
public EntityRef get() {
EntityRef characterEntity = localPlayer.getCharacterEntity();
CharacterComponent characterComponent = characterEntity.getComponent(CharacterComponent.class);
return characterComponent.predictedInteractionTarget;
}
});
Last edited by a moderator: