MCPcopy Create free account
hub / github.com/OpenLoco/OpenLoco / updateSegmentCrashed

Method updateSegmentCrashed

src/OpenLoco/src/Vehicles/VehicleBogie.cpp:167–297  ·  view source on GitHub ↗

0x004AA68E

Source from the content-addressed store, hash-verified

165
166 // 0x004AA68E
167 void VehicleBogie::updateSegmentCrashed()
168 {
169 Speed32 speed = Speed32(var_5A & 0x7FFFFFFF);
170 bool isComponentDestroyed = this->var_5A & (1U << 31);
171 speed = speed - (speed / 64);
172 if (speed <= 2.0_mph)
173 {
174 speed = 0.0_mph;
175 }
176
177 this->var_5A = speed.getRaw() | (isComponentDestroyed ? (1U << 31) : 0);
178
179 auto& distances = getVehicleUpdateDistances();
180 distances.unkDistance1 = speed.getRaw() / 128;
181 distances.unkDistance2 = speed.getRaw() / 128;
182
183 this->updateRoll(distances.unkDistance1);
184
185 if (isComponentDestroyed)
186 {
187 if (speed >= 1.0_mph)
188 {
189 const auto distanceTravelled = speed.getRaw() / 16;
190 auto xyDistance = Math::Trigonometry::computeXYVector(distanceTravelled, spriteYaw);
191
192 uint16_t xDistanceLow = xyDistance.x & 0x0000FFFF;
193 uint16_t yDistanceLow = xyDistance.y & 0x0000FFFF;
194 // This is being casted to uint32_t as we want a negative value to round away from zero
195 // this is due to splitting the precision of the distance into two parts
196 World::Pos2 distanceWorld(static_cast<uint32_t>(xyDistance.x) / 65536, static_cast<uint32_t>(xyDistance.y) / 65536);
197 // We are storing the lower precision in tileX and tileY they aren't actually being used as tileX and tileY.
198 // Yay reusing fields for different purposes means we need to be careful with the sign of the type
199 int32_t newTileX = static_cast<uint16_t>(this->tileX) + xDistanceLow;
200 if (newTileX >= 0x00010000)
201 {
202 distanceWorld.x++;
203 }
204 this->tileX = newTileX & 0x0000FFFF;
205
206 int32_t newTileY = static_cast<uint16_t>(this->tileY) + yDistanceLow;
207 if (newTileY >= 0x00010000)
208 {
209 distanceWorld.y++;
210 }
211 this->tileY = newTileY & 0x0000FFFF;
212
213 this->tileBaseZ++;
214 int16_t zDistance = this->tileBaseZ / 32;
215
216 // Calculate new position - but don't update yet!! This is pushed to the stack.
217 World::Pos3 newPosition{ position + World::Pos3(distanceWorld, -zDistance) };
218
219 if (!destroyedBogieCheckForCollision(*this, position))
220 {
221 World::Pos3 positionToTest = { newPosition.x, newPosition.y, this->position.z };
222 if (destroyedBogieCheckForCollision(*this, positionToTest))
223 {
224 newPosition.x = this->position.x;

Callers

nothing calls this directly

Calls 12

updateRollMethod · 0.95
computeXYVectorFunction · 0.85
getHeightFunction · 0.85
playSoundFunction · 0.85
hasVehicleFlagsMethod · 0.80
moveToMethod · 0.80
updateTrackMotionMethod · 0.80
createFunction · 0.50
getRawMethod · 0.45
hasFlagsMethod · 0.45

Tested by

no test coverage detected