meta data for this page
Vehicles/VehicleScripts/AnimatedParts.lua
AnimatedParts allows to add doors or other animated parts to a vehicle. The player can then click onto these parts to open or close them (one animation per part allowed).
25 AnimatedParts = AnimatedParts or {};
AnimatedParts:load(dataTable)
Initializes this vehicle script and fetches some data from the vehicle's configuration.
29 function AnimatedParts:load(dataTable) 30 -- currently only supports doors 31 self.setAnimatedPartState = VehicleManager:newFunction("setAnimatedPartState"); 32 self.getMayOpenDoors = AnimatedParts.getMayOpenDoors; 33 34 self.animatedParts = {}; 35 36 if dataTable.animatedParts ~= nil then 37 for k, v in pairs(dataTable.animatedParts) do 38 local id = getChild(self.id, v.index or ""); 39 40 if id ~= 0 then 41 local ap = {}; 42 local key = #self.animatedParts + 1; 43 ap.id = id; 44 ap.colId = v.collision == nil and id or getChild(self.id, v.collision or ""); 45 ap.animationLength = Animation.getLength(ap.id); 46 47 ap.textOff = l10n.getDollar(v.textOff or "textOff"); 48 ap.textOn = l10n.getDollar(v.textOn or "textOn"); 49 ap.state = v.defaultState or false; 50 ap.targetPosition = ap.state and ap.animationLength or 0; 51 ap.position = ap.targetPosition; 52 ap.onEnterState = v.onEnterState; 53 ap.onLeaveState = v.onLeaveState; 54 55 ap.isExteriorDoor = v.isExteriorDoor or false; 56 57 Animation.sampleTime(ap.id, ap.position); 58 59 ControlElement.new(ap.colId); 60 ControlElement.setCallback(ap.colId, 1, function() self:setAnimatedPartState(key, not ap.state); end); 61 ControlElement.setName(ap.colId, ap.state and ap.textOff or ap.textOn); 62 63 -- exterior doors will always be closed when the vehicle starts moving 64 if ap.isExteriorDoor then 65 ControlElement.setActiveCallback(ap.colId, self, "getMayOpenDoors"); 66 end; 67 68 table.insert(self.animatedParts, ap); 69 end; 70 end; 71 end; 72 end;
AnimatedParts:destroy()
Destroys all control elements.
75 function AnimatedParts:destroy() 76 for k, ap in pairs(self.animatedParts) do 77 ControlElement.destroy(ap.colId); 78 end; 79 end;
AnimatedParts:saveToTable(tbl)
Writes the current states of all animated parts to the savegame.
83 function AnimatedParts:saveToTable(tbl) 84 if tbl == nil then return end; 85 86 tbl.animatedParts = {}; 87 for k, ap in pairs(self.animatedParts) do 88 tbl.animatedParts[k] = { 89 state = ap.state or false, 90 position = ap.position, 91 }; 92 end; 93 end;
AnimatedParts:loadFromTable(tbl)
Reads the current states of our animated parts from the savegame.
97 function AnimatedParts:loadFromTable(tbl) 98 if tbl == nil then return end; 99 if tbl.animatedParts == nil then return end; 100 101 for k, ap in pairs(self.animatedParts) do 102 local data = tbl.animatedParts[k]; 103 104 if data ~= nil then 105 ap.state = getNoNil(data.state, ap.state); 106 ap.position = getNoNil(data.position, ap.position); 107 108 self:setAnimatedPartState(k, ap.state); 109 110 -- force sample time 111 Animation.sampleTime(ap.id, ap.position); 112 end; 113 end; 114 end;
AnimatedParts:setAnimatedPartState(key, value, noEvent)
Call this function to move the animated part to the specified position. key
is the animated part's index, value
(bool) is the target position (true or false). For doors, true usually represents open. noEvent
(bool) specifies whether the multiplayer event shall be suppressed.
The corresponding network event is EventSetAnimatedPart.
120 function AnimatedParts:setAnimatedPartState(key, value, noEvent) 121 local ap = self.animatedParts[key]; 122 123 if ap == nil then return end; 124 125 ap.state = value; 126 ap.targetPosition = ap.state and ap.animationLength or 0; 127 ControlElement.setName(ap.colId, ap.state and ap.textOff or ap.textOn); 128 129 if not noEvent then 130 EventSetAnimatedPart:send(self, key, value); 131 end; 132 end;
AnimatedParts:onEnter(player)
For some vehicles, it makes sense to open or close doors (depending on the animated part's onEnterState
) when the player enters the vehicle.
136 function AnimatedParts:onEnter(player) 137 if not isLocalPlayer or not GameplaySettings.autoCloseDoors then 138 return; 139 end; 140 141 for key, ap in pairs(self.animatedParts) do 142 if ap.onEnterState ~= nil then 143 self:setAnimatedPartState(key, ap.onEnterState); 144 end; 145 end; 146 end;
AnimatedParts:onLeave(player, isLocalPlayer)
For some vehicles, it can also make sense to open or close doors (depending on the animated part's onLeaveState
) when the player leaves the vehicle.
150 function AnimatedParts:onLeave(player, isLocalPlayer) 151 if not isLocalPlayer or not GameplaySettings.autoCloseDoors then 152 return; 153 end; 154 155 for key, ap in pairs(self.animatedParts) do 156 if ap.onLeaveState ~= nil then 157 self:setAnimatedPartState(key, ap.onLeaveState); 158 end; 159 end; 160 end;
AnimatedParts:update(dt)
Updates the door positions every frame, and if necessary, resamples the animation.
164 function AnimatedParts:update(dt) 165 local closeDoors = self:getIsLocalPlayerEntered() and not self:getMayOpenDoors(); 166 for key, ap in pairs(self.animatedParts) do 167 if ap.isExteriorDoor and closeDoors then 168 self:setAnimatedPartState(key, false); 169 end; 170 if ap.position ~= ap.targetPosition then 171 ap.position = Utils.moveTowards(ap.position, ap.targetPosition, dt); 172 Animation.sampleTime(ap.id, ap.position); 173 end; 174 end; 175 end;
AnimatedParts:getMayOpenDoors()
Returns true whenever the vehicle is hardly moving (which means that doors etc may be opened).
179 function AnimatedParts:getMayOpenDoors() 180 return self.currentSpeed == nil or math.abs(self.currentSpeed) < 3 or not self:getIsActive(); 181 end; 182
AnimatedParts:writeResync()
Resynchronizes all variables when a new player joins the game. The data sent by writeResync
will be received by readResync
.
186 function AnimatedParts:writeResync() 187 for k, v in ipairs(self.animatedParts) do 188 streamWriteBool(v.targetPosition > 0.5 * v.animationLength); 189 end; 190 end; 191
AnimatedParts:readResync()
Resynchronizes all variables when a new player joins the game. The data sent by writeResync
will be received by readResync
.
195 function AnimatedParts:readResync() 196 for k, v in pairs(self.animatedParts) do 197 local state = streamReadBool(); 198 self:setAnimatedPartState(k, state, true); 199 end; 200 end
Copyright
All contents of this page may be used for modding use for Winter Resort Simulator - Season 2 only. Any use exceeding this regulation is not permitted.
Copyright (C) HR Innoways, 2021. All Rights Reserved.