48 from -= force_redirected *
Sign(from);
49 to += force_redirected * tdir;
59 else if (tval < -ffric)
74 for (int32_t index = 0; index <
object->Shape.VtxNum; index++)
89 for (int32_t index = 0; index <
object->Shape.VtxNum; index++)
111 for (int32_t index = 0; index <
object->Shape.VtxNum; index++)
115 return object->Shape.VtxFriction[index];
146 RemoveSolidMask(
true);
153 contact_coordinate = limit;
169 for (int32_t ccnat = 0; ccnat < 4; ccnat++)
194 if (target_x < lbound)
198 if (target_x > rbound)
227 if (target_y < tbound)
231 if (target_y > bbound)
252 int contact_bits = 0;
253 bool has_moved =
false;
254 bool has_contact =
false;
255 bool has_turned =
false;
256 bool lost_attachment =
false;
257 bool redirected_force_from_ydir_to_rdir =
false;
265 MovementDigFreeTargetArea();
270 uint32_t old_ocf =
OCF;
292 int steps_total = steps_x + steps_y;
297 bool prefer_vertical_movement = steps_y > steps_x;
298 if (prefer_vertical_movement)
300 step_mod = std::max(2, (1 + steps_total) / std::max(1, steps_x));
304 step_mod = std::max(2, (1 + steps_total) / std::max(1, steps_y));
309 int step_counter = 0;
312 step_counter = (step_counter + 1) % step_mod;
319 if (step_counter > 0)
321 if (prefer_vertical_movement)
332 if (prefer_vertical_movement)
344 int32_t step_target_x =
GetX() + step_x;
345 int32_t step_target_y =
GetY() + step_y;
349 lost_attachment =
true;
354 if (step_target_x !=
GetX() + step_x)
357 new_x =
itofix(step_target_x);
359 if (step_target_y !=
GetY() + step_y)
362 new_y =
itofix(step_target_y);
366 uint32_t border_hack_contacts = 0;
367 int32_t current_contacts =
ContactCheck(step_target_x, step_target_y, &border_hack_contacts);
368 if (current_contacts || border_hack_contacts)
371 contact_bits |= border_hack_contacts |
t_contact;
373 if (current_contacts)
376 if (step_target_x !=
GetX())
378 step_target_x =
GetX();
381 if (step_target_y !=
GetY())
383 step_target_y =
GetY();
393 uint32_t border_hack_contacts = 0;
395 if (current_contacts || border_hack_contacts)
398 contact_bits |=
t_contact | border_hack_contacts;
400 if (current_contacts)
420 if (current_contacts)
442 redirected_force_from_ydir_to_rdir =
true;
461 RemoveSolidMask(
true);
483 int32_t current_x =
GetX();
484 int32_t current_y =
GetY();
507 int32_t current_contacts =
ContactCheck(current_x, current_y);
508 if (current_contacts)
514 target_r =
fix_r = old_rotation;
518 if (current_contacts == 1 && !redirected_force_from_ydir_to_rdir)
528 if (current_x !=
GetX() || current_y !=
GetY())
547 if (has_moved || has_turned)
562 lost_attachment =
false;
625 while (normalized_rotation <
itofix(-180))
627 normalized_rotation += 360;
629 while (normalized_rotation >
itofix(180))
631 normalized_rotation -= 360;
644 fix_r = old_rotation;
683 RemoveSolidMask(
true);
754 bool should_remove =
true;
758 int parallaxity_x, parallaxity_y;
761 should_remove =
false;
764 should_remove =
true;
766 else if (
GetX() < 0 && !!parallaxity_x)
768 should_remove =
true;
772 should_remove =
true;
785 void C4Object::MovementDigFreeTargetArea()
812 bool hit_on_time =
true;
813 bool break_main_loop =
false;
814 int32_t target_x, target_y;
815 int32_t current_x =
fixtoi(x);
816 int32_t current_y =
fixtoi(y);
817 int32_t index = iterations;
826 if (xdir == 0 && ydir == 0 &&
GravAccel == 0)
831 if (ydir <= 0 &&
GravAccel <= 0 && current_y < 0)
850 current_x +=
Sign(target_x - current_x);
851 current_y +=
Sign(target_y - current_y);
855 break_main_loop =
true;
859 while ((current_x != target_x) || (current_y != target_y));
863 while (!break_main_loop);
const uint32_t OCF_HitSpeed1
const int32_t C4M_Vehicle
const uint32_t OCF_Rotate
const uint32_t OCF_HitSpeed3
const uint32_t OCF_HitSpeed2
const int32_t C4D_Border_Bottom
const int32_t C4D_StaticBack
const int32_t C4D_Border_Layer
const int32_t C4D_Border_Top
const int32_t C4D_Parallax
const int32_t C4D_Border_Sides
bool GBackLiquid(int32_t x, int32_t y)
bool DensityLiquid(int32_t dens)
int32_t GBackDensity(int32_t x, int32_t y)
const C4Real FloatFriction
bool SimFlight(C4Real &x, C4Real &y, C4Real &xdir, C4Real &ydir, int32_t min_density, int32_t max_density, int32_t &iterations)
bool SimFlightHitsLiquid(C4Real start_x, C4Real start_y, C4Real xdir, C4Real ydir)
bool ContactVtxCNAT(C4Object *object, BYTE cnat_dir)
const C4Real DefaultGravAccel
void RedirectForce(C4Real &from, C4Real &to, int32_t tdir)
const C4Real FixHalfCircle
void ApplyFriction(C4Real &tval, int32_t percent)
int32_t ContactVtxWeight(C4Object *object)
const char * CNATName(int32_t cnat)
const C4Real FixFullCircle
int32_t ContactVtxFriction(C4Object *object)
C4Fixed itofix(int32_t x)
int fixtoi(const C4Fixed &x)
bool Inside(T ival, U lbound, V rbound)
StdStrBuf FormatString(const char *szFmt,...)
int32_t DigFreeRect(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, C4Object *by_object=nullptr, bool no_dig2objects=false, bool no_instability_check=false)
int32_t GetHeight() const
int32_t DigFree(int32_t tx, int32_t ty, int32_t rad, C4Object *by_object=nullptr, bool no_dig2objects=false, bool no_instability_check=false)
void UpdateSolidMask(bool fRestoreAttachedObjects)
int32_t ContactCheck(int32_t at_x, int32_t at_y, uint32_t *border_hack_contacts=nullptr, bool collide_halfvehic=false)
C4PropList * GetAction() const
void CopyMotion(C4Object *from)
void UpdateFace(bool bUpdateShape, bool fTemp=false)
void GetParallaxity(int32_t *parX, int32_t *parY) const
bool Contact(int32_t cnat)
bool IsInLiquidCheck() const
void StopAndContact(C4Real &ctco, C4Real limit, C4Real &speed, int32_t cnat)
void ForcePosition(C4Real target_x, C4Real target_y)
void AssignDeath(bool fForced)
void AssignRemoval(bool exit_contents=false)
void MovePosition(int32_t dx, int32_t dy)
void VerticalBounds(C4Real &target_y)
void UpdateShape(bool bUpdateVertices=true)
void SideBounds(C4Real &target_x)
void DoMotion(int32_t mx, int32_t my)
int32_t GetPropertyInt(C4PropertyName k, int32_t default_val=0) const
C4PropertyName GetPropertyP(C4PropertyName k) const
C4Value Call(C4PropertyName k, C4AulParSet *pPars=nullptr, bool fPassErrors=false)
bool ContactCheck(int32_t cx, int32_t cy, uint32_t *border_hack_contacts=nullptr, bool collide_halfvehic=false)
int32_t VtxContactCNAT[C4D_MaxVertex]
bool Attach(int32_t &cx, int32_t &cy, BYTE cnat_pos)
int32_t VtxX[C4D_MaxVertex]