PathPlatform¶
A platform that moves on a set path defined by multiple absolute position vectors called nodes and can conditionally be stopped depending on the hit value of other NPCControl present on the map. Can be operated in loop mode using only 2 nodes or with multiple nodes in path mode with more options.
Data Arrays¶
data: The map entities ids to check for theirhitbeing true and if any are, it will tell the platform to set itshitto true and to start moving along its path in path mode. This is optional, the platform is considered as continually moving as normal without any elementsvectordata: The nodes the platform will travel in absolute positioningdialogues[0].x:The meaning depends on the mode:- In path mode, this is the starting node after truncating to int
- In loop mode, this is the starting
speedmultiplier(the starting node index) after truncating to int. This means only [0.0, 2.0[ are valid values
dialogues[0].y: The speed multiplier at which the platform moves.dialogues[1].x: if it's 1, it means to place the platform in loop mode by only using the first 2vectordataand disregard thecurrentnodelogicdialogues[1].y: Theactioncooldownto apply when the platform has reached the end of its path and it should go inactive.dialogues[2].x: The local scale of the entity.modelwill be multiplied by the 1/10 of this, but this is optional and the scale will not change if it is 0.1 or belowdialogues[2].y: If not 0, theelectimeof the GlowTrigger when the entity.originalidis theElectroPlatformAnimID. This is optional and the value defaults is 260.0
Additional data¶
speedmultiplier: OVERRIDEN (this is used as a value between 0.0 and 1.0 that represents the lerp factor of the platform position between 2 nodes as it moves)boxcol: If entity.originalidis theLilypadAnimID, theboxcolis created manually, but it doesn't remove the existing one meaning under these circumstances, the entity shouldn't be specified that it has one since it would make it so there's 2boxcolwith the loaded version not being accessible by the game
Setup¶
- entity.
rigidgets effectively locked by disabling gravity, making it kinematic and freezing all constraints - isStatic on the gameObject is set to false
nointeractis set to true- entity.
soundonpauseis set to true - entity.
modelscale is multiplied by a 1/10 ofdialogues[2].x - If
dialogues[1].xis 1 (loop mode) anddialogues[0].xis 1 (the starting node is the second one), thespeedmultiplieris set to 1.0 - If
dialogues[1].xis 0 (path mode):currentnodeis set todialogues[0].x- The position is set to the
vectordataat thecurrentnode - entity.
startposis set to the new position
- If the entity.
originalidis theLilypadAnimID:- The
scolis disabled - the
boxcolis recreated with trigger and a size of (5.0, 1.0, 5.0) which overrides all theboxcolfields obtained when loading the data.
- The
- entity.
alwaysactiveis set to true - entity.
modeltag is set toPlatformNoClock - If entity.
originalidis theElectroPlatformAnimID, a GlowTrigger is added on the first child of themodel:getactivecolorfromstartis set to trueparentis set to this NPCControlglowpartsis initialised to a single element corresponding to the MeshRenderer of the first child of themodelelectimeis initialised to 260.0 unlessdialogues[2].yexists and isn't 0 where it will take that value instead
Update¶
If entity.originalid is the Lilypad AnimId, the boxcol if present is kept enabled, otherwise, its enabled will bet set to the hit value.
From there, the platform can operate in 2 distinct modes: forever loop between the first 2 vectordata where the current one is tracked by speedmultiplier or follow a series of nodes defined in vectordata where the current one is tracked by currentnode. The former is done if dialogues[1].x is 1, the latter is done otherwise.
Loop mode¶
This is a much simpler mode where only the first 2 vectordata are used as nodes.
In this mode, hit is set to true and it is never toggled back. This means the platform will continually move according to the speedmultiplier field which serves as the factor of the position lerp to perform between vectordata[0] and vectordata[1].
On the first update, if dialogues[0].x isn't negative (which it shouldn't be on the first Update), it will be the starting value of speedmultiplier. This is a one off: after setting the field, it is reset to -1. It should be noted that the value set is a cast to int meaning it can only be [0.0, 2.0[ which coresponds to the starting node chosen among the 2.
The platform is considered active when either data is empty or any of its elements refers to a map NPCControl whose hit is true. If it is active, speedmultiplier gets incremented by the game's frametime * dialogues[0].y / 1000.0. If it's inactive, it gets decremented instead. Basically, the platform moves forward when active and backward when inactive.
The position set portion starts by clamping speedmultiplier from 0.0 to 1.0 and then setting the position using a Vector3.Lerp from vectordata[0] to vectordata[1] with a factor of speedmultiplier.
Unless entity.originalid is the Lilypad AnimId, speedmultiplier is below 1.0 and the entity.sound is playing, then PlaySound is called on the entity with the PlatformMove clip set to loop.
Path mode¶
What happens each updates depends on the value of hit which gets toggled on and off in a very systematic manner. The details involves many different fields that interacts with each other:
actioncooldown: The cooldown used to stop movement whenever the platform reaches its last node AND it is considered deactivated. This is refreshed to bedialogues[1].yeach time the platform goes to a new node withhitbeing set to true.speedmultiplier: The factor to use when lerping the platform positions between nodes. It's set to 0.0 when going to a new node until it reaches 1.0+. It progressively increases by the frametime of the game *dialogues[0].y/ 1000.0.bounces: The previous node index visited which will be used as thefromvector when lerping.currentnode: The next node index to visit which will be used as thetovector when lerping.
When hit is false¶
Before anything happens, the entity's sound is set to not loop and its model tag is set to Platform.
The platform is considered active when either data is empty or any of its elements refers to a map NPCControl whose hit is true. When a platform is active, it will have its hit set to true on the first update in which it was false. This will cause the fields to be set in such a way that bounces will always lag behind by 1 from currentnode when going forward. When the platform reaches the end and it's still active, it will set currentnode to 0 which will make the platform go back to its starting point, but ignoring all the nodes, it simply moves straight towards the start and continues from there.
But it is possible for the platform to go inactive during its forward path. When this happens, this is where the actioncooldown comes into play. It will be exhausted which will make the platform stationnary until it expires. When it does expire, if the platform's currentnode is higher than 0 (it's further than the starting node), it will decrement it, but have bounces be one node above. This essentially makes the platform go backwards from the nodes list, but following its movement path until the start (with cooldown applied) and it also sets hit to true.
When hit is true¶
There is a special case before anything happens: whenever hit goes to true, it is possible that currentnode and bounces points to the same node. It can happen if there's only one node defined in vectordata. If this occurs, the update logic just ends abrutply because there is no need to move the platform and it will remain stationnary forever.
The entity.model tag is set to PlatformNoClock. Unless entity.originalid is the Lilypad AnimId and the entity's sound is playing, then PlaySound is called on the entity with the PlatformMove clip set to loop.
From there, this is where the movement is done until speedmultipiler reaches 1.0 or above in which case, it's reset to 0.0 and hit is set to false again.
When moving the platform, the lerping using will be the standard Vector3.Lerp, but there is a special case if there's only 2 nodes in vectordata. When this happens, the game's SmoothLerp is used instead which is a much slower and spread out lerping procedure.
OnTriggerEnter if the other collider is the player¶
There is some dead logic here where nothing happens, but the conditions are all of these being true:
- The current area is
WildGrasslands - The entity
originalidis theLilypadanimid - The player entity is
onground
Hazards.OnObjectStay¶
If the NPCControl passed has this type, it returns true which allows it to stay in collision with the Hazards.
Effects of the Platform and PlatformNoClock¶
There are some special logic implicated by the platform having these tags. Mainly, the game will often child GameObjects of interests to the platform when they are getting on it and child them back to where they were when no longer being on it.
Specififcally, the GroundDetector's OnTriggerStay will check if the other collider has either of these tags and do the childing of the entity if it does. Additionally, the entity.noclock is set to true if the tag is PlatformNoClock and to false if it's Platform. On the component's OnTriggerExit, this is all undone, but there's a special case for the player or PFolower where it's parented to the root instead of the map.
The Hornable component also does this which is related to the ice cube of a Dropplet. If the other collider has either tag, OnTriggerEnter / OnCollisionEnter will child the other transform to the platform. This is undone on the component's OnTriggerExit if the other collider has either of the tags.
As for what the entity.noclock does, normally, on MainManager.DoClock, the method RefreshPlayer is called when the player is free and it would normally set the onground to false and root all playerdata entities (this incidentally has a known issue where the frictions gets toggled off for one frame every second). noclock is a field that will prevent this logic from happening so it prevents the rooting of the player to the scene. In the case of the PathPlatform, it means that this logic doesn't happen as long as the player is on the platform AND it is active (the logic is free to do its thing when the platform goes inactive).