Table of Contents
The Ripper is a simple single-passenger hover bike, designed to demonstrate vehicle implementation. In this section, Ripper's implementation is detailed to help in its use as a basis for new vehicles.
The Ripper consists of the following files:
-
fantasydemo/res/scripts/base/Ripper.py
-
fantasydemo/res/scripts/cell/Ripper.py
-
fantasydemo/res/scripts/client/Ripper.py
-
fantasydemo/res/scripts/entity_defs/Ripper.def
-
fantasydemo/res/scripts/editor/Ripper.py
It also requires an entry in
fantasydemo/res/scripts/entities.xml
file, and some
functionality in the Avatar's client and cell.
The Ripper's base is empty, as it does not need to do more than is provided by the default base of FantasyDemo.
The Ripper's cell manages control of the Ripper, and is responsible for notifying all interested clients of such changes.
When the Ripper is first created, the cell has control of its movements, but passes this ability to clients as they attempt to use it.
The Ripper's cell contains the methods described in the list below:
-
mountVehicle( self, sourceAvatarID )
Mount process stage 4 of 8, this is a Ripper specified method for mounting the vehicle. In this method, control is transferred to the client, and the specified avatar's cell is requested to board the Ripper. The board request of the avatar forms stage 5 of 8 of the dismount process.
-
passengerBoarded( self, sourceAvatarID )
Mount process stage 6 of 8, this is a callback from the pilot's cell, and is specific to the Avatar implementation
-
dismountVehicle( self, sourceAvatarID )
Dismount process stage 3 of 7, this is a Ripper-specific method for dismounting the vehicle In this method, the Ripper's cell takes back control of its movement, and requests that the avatar alight. The avatar's alight request forms stage 4 of 7 of the dismount process.
-
passengerAlighted( self, sourceAvatarID )
Dismount process stage 5 of 7, this is a callback from the pilot's cell, and is specific to the Avatar implementation.
-
onLoseControlledBy( self, id )
This is a server event handler that should be implemented by all vehicles that transfer control to a client at some point. It is called when the connection to a passenger's client is lost, and so gives the vehicle the opportunity to return to a good state
The client side of the Ripper is the largest part of the implementation, as it handles interaction and animation.
Ripper's client contains the methods described in the list below:
-
enterWorld( self )
Implemented by most entities, for the Ripper contains cosmetic code that does not affect functionality. Particle systems, shadows, and the initial state of animation is set up. The passenger will always enter the world after the vehicle, requiring a separate
onPassengerEnterWorld()
. -
prerequisites( self )
Part of the asynchronous loading system employed by the BigWorld client. By returning a list of assets used by the Ripper, pauses from blocking loads can be avoided.
-
passengerEnterWorld( self, pilot )
Called by the Avatar implementation in FantasyDemo when an Avatar enters the world on a vehicle. It is used by the Ripper to setup the pilot model and animation.
-
leaveWorld( self )
Implemented by most entities, for the Ripper contains only some minor cleanup code for particle systems and shadows. The client caches entities that leave the area of interest, so be sure that the vehicle will return to a good state if
enterWorld()
is called on it later. -
use( self )
Mount process stage 1 of 8, this is an event handler override for when the entity is used. In the case of the Ripper, it is used to initiate the mounting process.
-
walkToMountPosition( self, success )
Mount process stage 2 of 8, this recursive function lines up the player and the Ripper for the mounting animations by using the seek commands in the player's physics object
-
arriveAtMountPosition( self, success )
Mount process stage 3 of 8, this callback is given to the seek function to notify the Ripper when the player has arrived. On success, the client-side Ripper will contact its cell and attempt to acquire control for this client.
-
mountVehicle( self, succeeded, pilotAvatarID )
Mount process stage 7 of 8, this is a broadcast sent to all clients interested in this Ripper. It informs them that an Avatar is mounting the vehicle — the affected Avatar also receives this call, and uses the ID parameter to identify itself. The Ripper becomes the player in this case, and plays the mounting animations to demonstrate this
-
finishMountVehicle( self )
Mount process stage 8 of 8, this is called at the end of the mount animation using the
BigWorld.callback()
[1] mechanism. It completes the mount process, unlocking the Ripper controls. -
dismountVehicle( self, pilotAvatarID )
Dismount process stage 6 of 7, this is the second broadcast method used by the cell to notify clients of the Ripper's dismount in progress. As in
mountVehicle()
, the pilot ID is provided to identify the client dismounting. -
finishDismountVehicle( self )
Dismount process stage 7 of 7. Completing the dismount animation, the player's model is returned to the avatar, which is then released back to user control.
PlayerRipper's client contains the methods described in the list below:
-
onBecomePlayer( self )
Event handler triggered when the vehicle becomes a PlayerRipper. Note that the PlayerRipper's constructor is not called, as the object is constructed as a normal Ripper and then later changes type to PlayerRipper.
-
setupKeyBindings( self )
Method used by the Ripper to setup the player's controls.
-
onBecomeNonPlayer( self )
Event triggered when the Ripper changes back into a plain Ripper object. Upon receiving this, clean up any members created during onBecomePlayer event, such as key bindings.
-
handleKeyEvent( self, isDown, key, mods )
Calls functions mapped to key inputs. This is basically the same as the one used in the Fantasydemo Avatar.
-
updateThrust( self )
Method called as part of the key event handling process to update the physics object and animations.
-
beginDismount( self, isDown )
Dismount process stage 1 of 7, this method shuts down the Ripper, so that it will fall to the ground, ready for the player to alight.
-
dismountStep( self )
Dismount process stage 2 of 7, this method finishes the landing initiated in beginDismount, before initiating the cell's dismount process.
-
checkAnims( self )
Method called to tick the animation of hover vehicles, as the generic action matcher is not suitable for this style of vehicle.
-
playTransitionAction( self, act, oldTurn, oldMove )
Utility function used by checkAnims to blend between different states of turning.
-
handleConsoleInput( self, string )
Method that passes its calls onto the avatar that handles the chat console.
-
onCollide( self, newMomentum, collidePosition, severity, triangleFlags )
Method used by the Rippers to trigger sounds and particle effects. The Ripper is a physical body in the world, and so can receive collision callbacks.
-
moveForward( self, isDown )
Key event handlers that translate the relevant 'key down' state into a numerical one or zero. For use in
-
moveBackward( self, isDown )
See the moveForward( self, isDown ) entry above.
-
turnLeft( self, isDown )
See the moveForward( self, isDown ) entry above.
-
turnRight( self, isDown )
See the moveForward( self, isDown ) entry above.
-
moveUpward( self, isDown )
See the moveForward( self, isDown ) entry above.
-
updateThrust
See the moveForward( self, isDown ) entry above.
Located under fantasydemo/res/scripts/entity_defs
, the
Ripper.def
definition file for the Ripper contains
the following properties:
-
pilotID
Current pilot of the vehicle It is used in client-side checks to prevent multiple mount attempts, and also for displaying the pilot model on the vehicle.
The file declares the following client methods:
-
mountVehicle()
Function call sent to all interested clients, to notify them of an avatar boarding the Ripper.
-
dismountVehicle()
Function call sent to all interested clients, to notify them of an avatar dismounting the Ripper.
It also declares the following cell methods:
-
mountVehicle()
Function used by the client to actually mount the vehicle and gain control of it. This function will fail if the Ripper is already occupied.
-
dismountVehicle()
Function called by either the client or the controller lost event handler to return the Ripper to a mountable state.
-
passengerBoarded()
Callback received from the avatar when it has boarded the vehicle entity.
-
passengerAlighted()
Callback received from the avatar when it has alighted from the vehicle entity.
Located under fantasydemo/res/scripts/editor
, the purpose
of the editor Ripper is to provide the world editor with a representative
model that it can display.
For the Ripper, we just use its model.
To work with vehicles, the Avatar entity must implement the client methods below:
-
enterWorld( self )
In order to display correctly on clients observing other Avatars riding Rippers, the Avatar must notify its vehicle when it enters the world, as this will be after the vehicle enters it. In FantasyDemo, this is done using the function
onPassengerEnterWorld()
.
It must also implement the following cell methods:
-
requestBoardVehicle( self, sourceVehicleID )
Because the entity board and alight functions cannot be called on a ghost cell, they need to be wrapped in ghost-safe functions defined in the definition file.
-
requestAlightVehicle( self, sourceVehicleID )
Similar to
requestBoardVehicle()
this provides a ghost-safe wrapper for the entity alight vehicle functionality. It also does some checking, to make it safe to call multiple times before remounting. -
chat()
In FantasyDemo, the chat system is implemented through the avatar cell. Because of this, the Ripper assumes its implementation.