OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4Movement.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Object motion, collision, friction */
19 
20 #include "C4Include.h"
21 #include "object/C4Def.h"
22 #include "object/C4Object.h"
23 
24 #include "script/C4Effect.h"
25 #include "game/C4Physics.h"
26 #include "landscape/C4SolidMask.h"
27 #include "landscape/C4Landscape.h"
28 #include "game/C4Game.h"
29 
30 /* Some physical constants */
31 
34 const C4Real FixFullCircle=itofix(360),FixHalfCircle=FixFullCircle/2;
37 const C4Real HitSpeed1=C4REAL100(150); // Hit Event
38 const C4Real HitSpeed2=itofix(2); // Cross Check Hit
39 const C4Real HitSpeed3=itofix(6); // Scale disable, kneel
40 const C4Real HitSpeed4=itofix(8); // Flat
42 
43 /* Some helper functions */
44 
45 void RedirectForce(C4Real &from, C4Real &to, int32_t tdir)
46 {
47  C4Real fred;
48  fred=std::min(Abs(from), FRedirect);
49  from-=fred*Sign(from);
50  to+=fred*tdir;
51 }
52 
53 void ApplyFriction(C4Real &tval, int32_t percent)
54 {
55  C4Real ffric=FFriction*percent/100;
56  if (tval>+ffric) { tval-=ffric; return; }
57  if (tval<-ffric) { tval+=ffric; return; }
58  tval=0;
59 }
60 
61 // Compares all Shape.VtxContactCNAT[] CNAT flags to search flag.
62 // Returns true if CNAT match has been found.
63 
64 bool ContactVtxCNAT(C4Object *cobj, BYTE cnat_dir)
65 {
66  int32_t cnt;
67  bool fcontact=false;
68  for (cnt=0; cnt<cobj->Shape.VtxNum; cnt++)
69  if (cobj->Shape.VtxContactCNAT[cnt] & cnat_dir)
70  fcontact=true;
71  return fcontact;
72 }
73 
74 // Finds first vertex with contact flag set.
75 // Returns -1/0/+1 for relation on vertex to object center.
76 
77 int32_t ContactVtxWeight(C4Object *cobj)
78 {
79  int32_t cnt;
80  for (cnt=0; cnt<cobj->Shape.VtxNum; cnt++)
81  if (cobj->Shape.VtxContactCNAT[cnt])
82  {
83  if (cobj->Shape.VtxX[cnt]<0) return -1;
84  if (cobj->Shape.VtxX[cnt]>0) return +1;
85  }
86  return 0;
87 }
88 
89 // ContactVtxFriction: Returns 0-100 friction value of first
90 // contacted vertex;
91 
93 {
94  int32_t cnt;
95  for (cnt=0; cnt<cobj->Shape.VtxNum; cnt++)
96  if (cobj->Shape.VtxContactCNAT[cnt])
97  return cobj->Shape.VtxFriction[cnt];
98  return 0;
99 }
100 
101 const char *CNATName(int32_t cnat)
102 {
103  switch (cnat)
104  {
105  case CNAT_None: return "None";
106  case CNAT_Left: return "Left";
107  case CNAT_Right: return "Right";
108  case CNAT_Top: return "Top";
109  case CNAT_Bottom: return "Bottom";
110  case CNAT_Center: return "Center";
111  }
112  return "Undefined";
113 }
114 
115 bool C4Object::Contact(int32_t iCNAT)
116 {
118  {
119  return !! Call(FormatString(PSF_Contact, CNATName(iCNAT)).getData());
120  }
121  return false;
122 }
123 
124 void C4Object::DoMotion(int32_t mx, int32_t my)
125 {
127  fix_x += mx; fix_y += my;
128 }
129 
130 void C4Object::StopAndContact(C4Real & ctco, C4Real limit, C4Real & speed, int32_t cnat)
131 {
132  ctco = limit;
133  speed = 0;
134  Contact(cnat);
135 }
136 
137 int32_t C4Object::ContactCheck(int32_t iAtX, int32_t iAtY, uint32_t *border_hack_contacts, bool collide_halfvehic)
138 {
139  // Check shape contact at given position
140  Shape.ContactCheck(iAtX,iAtY,border_hack_contacts,collide_halfvehic);
141 
142  // Store shape contact values in object t_contact
144 
145  // Contact script call for the first contacted cnat
146  if (Shape.ContactCNAT)
147  for (int32_t ccnat=0; ccnat<4; ccnat++) // Left, right, top bottom
148  if (Shape.ContactCNAT & (1<<ccnat))
149  if (Contact(1<<ccnat))
150  break; // Will stop on first positive return contact call!
151 
152  // Return shape contact count
153  return Shape.ContactCount;
154 }
155 
156 // Stop the object and do contact calls if it collides with the border
158 {
159  // layer bounds
161  {
162  C4PropList* pActionDef = GetAction();
163  if (!pActionDef || pActionDef->GetPropertyP(P_Procedure) != DFA_ATTACH)
164  {
165  C4Real lbound = itofix(Layer->GetX() + Layer->Shape.GetX() - Shape.GetX()),
166  rbound = itofix(Layer->GetX() + Layer->Shape.GetX() + Layer->Shape.Wdt - (Shape.GetX() + Shape.Wdt));
167  if (ctcox < lbound) StopAndContact(ctcox, lbound, xdir, CNAT_Left);
168  if (ctcox > rbound) StopAndContact(ctcox, rbound, xdir, CNAT_Right);
169  }
170  }
171  // landscape bounds
172  C4Real lbound = itofix(0 - Shape.GetX()),
173  rbound = itofix(::Landscape.GetWidth() - (Shape.GetX() + Shape.Wdt));
174  if (ctcox < lbound && GetPropertyInt(P_BorderBound) & C4D_Border_Sides)
175  StopAndContact(ctcox, lbound, xdir, CNAT_Left);
176  if (ctcox > rbound && GetPropertyInt(P_BorderBound) & C4D_Border_Sides)
177  StopAndContact(ctcox, rbound, xdir, CNAT_Right);
178 }
179 
181 {
182  // layer bounds
184  {
185  C4PropList* pActionDef = GetAction();
186  if (!pActionDef || pActionDef->GetPropertyP(P_Procedure) != DFA_ATTACH)
187  {
188  C4Real tbound = itofix(Layer->GetY() + Layer->Shape.GetY() - Shape.GetY()),
189  bbound = itofix(Layer->GetY() + Layer->Shape.GetY() + Layer->Shape.Hgt - (Shape.GetY() + Shape.Hgt));
190  if (ctcoy < tbound) StopAndContact(ctcoy, tbound, ydir, CNAT_Top);
191  if (ctcoy > bbound) StopAndContact(ctcoy, bbound, ydir, CNAT_Bottom);
192  }
193  }
194  // landscape bounds
195  C4Real tbound = itofix(0 - Shape.GetY()),
196  bbound = itofix(::Landscape.GetHeight() - (Shape.GetY() + Shape.Hgt));
197  if (ctcoy < tbound && GetPropertyInt(P_BorderBound) & C4D_Border_Top)
198  StopAndContact(ctcoy, tbound, ydir, CNAT_Top);
199  if (ctcoy > bbound && GetPropertyInt(P_BorderBound) & C4D_Border_Bottom)
200  StopAndContact(ctcoy, bbound, ydir, CNAT_Bottom);
201 }
202 
204 {
205  int32_t iContact=0;
206  bool fAnyContact=false; int iContacts = 0;
207  BYTE fTurned=0,fRedirectYR=0,fNoAttach=0;
208  // Restrictions
209  if (Def->NoHorizontalMove) xdir=0;
210  // Dig free target area
211  C4PropList* pActionDef = GetAction();
212  if (pActionDef)
213  if (pActionDef->GetPropertyInt(P_DigFree))
214  {
215  int ctcox, ctcoy;
216  // Shape size square
217  if (pActionDef->GetPropertyInt(P_DigFree)==1)
218  {
219  ctcox=fixtoi(fix_x+xdir); ctcoy=fixtoi(fix_y+ydir);
220  ::Landscape.DigFreeRect(ctcox+Shape.GetX(),ctcoy+Shape.GetY(),Shape.Wdt,Shape.Hgt,this);
221  }
222  // Free size round (variable size)
223  else
224  {
225  ctcox=fixtoi(fix_x+xdir); ctcoy=fixtoi(fix_y+ydir);
226  int32_t rad = pActionDef->GetPropertyInt(P_DigFree);
227  if (Con<FullCon) rad = rad*6*Con/5/FullCon;
228  ::Landscape.DigFree(ctcox,ctcoy-1,rad,this);
229  }
230  }
231 
232  // store previous movement and ocf
233  C4Real oldxdir(xdir), oldydir(ydir);
234  uint32_t old_ocf = OCF;
235 
236  bool fMoved = false;
237  C4Real new_x = fix_x + xdir;
238  C4Real new_y = fix_y + ydir;
239  SideBounds(new_x);
240 
241  if (!Action.t_attach) // Unattached movement = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
242  {
243  // Horizontal movement - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
244  // Move to target
245  while (fixtoi(new_x) != fixtoi(fix_x))
246  {
247  // Next step
248  int step = Sign(new_x - fix_x);
249  uint32_t border_hack_contacts = 0;
250  iContact=ContactCheck(GetX() + step, GetY(), &border_hack_contacts);
251  if (iContact || border_hack_contacts)
252  {
253  fAnyContact=true; iContacts |= t_contact | border_hack_contacts;
254  }
255  if (iContact)
256  {
257  // Abort horizontal movement
258  new_x = fix_x;
259  // Vertical redirection (always)
260  RedirectForce(xdir,ydir,-1);
261  ApplyFriction(ydir,ContactVtxFriction(this));
262  }
263  else // Free horizontal movement
264  {
265  DoMotion(step, 0);
266  fMoved = true;
267  }
268  }
269  // Vertical movement - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
270  // Movement target
271  new_y = fix_y + ydir;
272  // Movement bounds (vertical)
273  VerticalBounds(new_y);
274  // Move to target
275  while (fixtoi(new_y) != fixtoi(fix_y))
276  {
277  // Next step
278  int step = Sign(new_y - fix_y);
279  if ((iContact=ContactCheck(GetX(), GetY() + step, nullptr, ydir > 0)))
280  {
281  fAnyContact=true; iContacts |= t_contact;
282  new_y = fix_y;
283  // Vertical contact horizontal friction
284  ApplyFriction(xdir,ContactVtxFriction(this));
285  // Redirection slide or rotate
286  if (!ContactVtxCNAT(this,CNAT_Left))
287  RedirectForce(ydir,xdir,-1);
288  else if (!ContactVtxCNAT(this,CNAT_Right))
289  RedirectForce(ydir,xdir,+1);
290  else
291  {
292  // living things are always capable of keeping their rotation
293  if (OCF & OCF_Rotate) if (iContact==1) if (!Alive)
294  {
295  RedirectForce(ydir,rdir,-ContactVtxWeight(this));
296  fRedirectYR=1;
297  }
298  ydir=0;
299  }
300  }
301  else // Free vertical movement
302  {
303  DoMotion(0,step);
304  fMoved = true;
305  }
306  }
307  }
308  if (Action.t_attach) // Attached movement = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
309  {
310  VerticalBounds(new_y);
311  // Move to target
312  do
313  {
314  // Set next step target
315  int step_x = 0, step_y = 0;
316  if (fixtoi(new_x) != GetX())
317  step_x = Sign(fixtoi(new_x) - GetX());
318  else if (fixtoi(new_y) != GetY())
319  step_y = Sign(fixtoi(new_y) - GetY());
320  int32_t ctx = GetX() + step_x;
321  int32_t cty = GetY() + step_y;
322  // Attachment check
323  if (!Shape.Attach(ctx,cty,Action.t_attach))
324  fNoAttach=1;
325  else
326  {
327  // Attachment change to ctx/cty overrides target
328  if (ctx != GetX() + step_x)
329  {
330  xdir = Fix0; new_x = itofix(ctx);
331  }
332  if (cty != GetY() + step_y)
333  {
334  ydir = Fix0; new_y = itofix(cty);
335  }
336  }
337  // Contact check & evaluation
338  uint32_t border_hack_contacts = 0;
339  iContact=ContactCheck(ctx,cty,&border_hack_contacts);
340  if (iContact || border_hack_contacts)
341  {
342  fAnyContact=true; iContacts |= border_hack_contacts | t_contact;
343  }
344  if (iContact)
345  {
346  // Abort movement
347  if (ctx != GetX())
348  {
349  ctx = GetX(); new_x = fix_x;
350  }
351  if (cty != GetY())
352  {
353  cty = GetY(); new_y = fix_y;
354  }
355  }
356  DoMotion(ctx - GetX(), cty - GetY());
357  fMoved = true;
358  }
359  while (fixtoi(new_x) != GetX() || fixtoi(new_y) != GetY());
360  }
361 
362  if(fix_x != new_x || fix_y != new_y)
363  {
364  fMoved = true;
366  fix_x = new_x;
367  fix_y = new_y;
368  }
369  // Rotation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
370  if (OCF & OCF_Rotate && !!rdir)
371  {
372  C4Real target_r = fix_r + rdir * 5;
373  // Rotation limit
374  if (Def->Rotateable>1)
375  {
376  if (target_r > itofix(Def->Rotateable))
377  { target_r = itofix(Def->Rotateable); rdir=0; }
378  if (target_r < itofix(-Def->Rotateable))
379  { target_r = itofix(-Def->Rotateable); rdir=0; }
380  }
381  int32_t ctx=GetX(); int32_t cty=GetY();
382  // Move to target
383  while (fixtoi(fix_r) != fixtoi(target_r))
384  {
385  // Save step undos
386  C4Real lcobjr = fix_r; C4Shape lshape=Shape;
387  // Try next step
388  fix_r += Sign(target_r - fix_r);
389  UpdateShape();
390  // attached rotation: rotate around attachment pos
391  if (Action.t_attach && !fNoAttach)
392  {
393  // more accurately, attachment should be evaluated by a rotation around the attachment vertex
394  // however, as long as this code is only used for some surfaces adjustment for large vehicles,
395  // it's enough to assume rotation around the center
396  ctx=GetX(); cty=GetY();
397  // evaluate attachment, but do not bother about attachment loss
398  // that will then be done in next execution cycle
399  Shape.Attach(ctx,cty,Action.t_attach);
400  }
401  // check for contact
402  if ((iContact=ContactCheck(ctx,cty))) // Contact
403  {
404  fAnyContact=true; iContacts |= t_contact;
405  // Undo step and abort movement
406  Shape=lshape;
407  target_r = fix_r = lcobjr;
408  // last UpdateShape-call might have changed sector lists!
409  UpdatePos();
410  // Redirect to GetY()
411  if (iContact==1) if (!fRedirectYR)
412  RedirectForce(rdir,ydir,-1);
413  // Stop rotation
414  rdir=0;
415  }
416  else
417  {
418  fTurned=1;
419  if (ctx != GetX() || cty != GetY())
420  {
421  fix_x = itofix(ctx); fix_y = itofix(cty);
422  }
423  }
424  }
425  // Circle bounds
426  if (target_r < -FixHalfCircle) { target_r += FixFullCircle; }
427  if (target_r > +FixHalfCircle) { target_r -= FixFullCircle; }
428  fix_r = target_r;
429  }
430  // Reput solid mask if moved by motion
431  if (fMoved || fTurned) UpdateSolidMask(true);
432  // Misc checks ===========================================================================================
433  // InLiquid check
434  // this equals C4Object::UpdateLiquid, but the "fNoAttach=false;"-line
435  if (IsInLiquidCheck()) // In Liquid
436  {
437  if (!InLiquid) // Enter liquid
438  {
439  if (OCF & OCF_HitSpeed2)
440  if (Mass>3) Splash();
441  fNoAttach=false;
442  InLiquid=1;
443  }
444  }
445  else // Out of liquid
446  {
447  if (InLiquid) // Leave liquid
448  InLiquid=0;
449  }
450  // Contact Action
451  if (fAnyContact)
452  {
453  t_contact = iContacts;
454  ContactAction();
455  }
456  // Attachment Loss Action
457  if (fNoAttach)
458  NoAttachAction();
459  // Movement Script Execution
460  if (fAnyContact)
461  {
462  C4AulParSet pars(fixtoi(oldxdir, 100), fixtoi(oldydir, 100));
463  if (old_ocf & OCF_HitSpeed1) Call(PSF_Hit, &pars);
464  if (old_ocf & OCF_HitSpeed2) Call(PSF_Hit2, &pars);
465  if (old_ocf & OCF_HitSpeed3) Call(PSF_Hit3, &pars);
466  }
467  // Rotation gfx
468  if (fTurned)
469  UpdateFace(true);
470  else
471  // pos changed?
472  if (fMoved) UpdatePos();
473 }
474 
476 {
477  // def allows stabilization?
478  if (Def->NoStabilize) return;
479  // normalize angle
480  C4Real nr = fix_r;
481  while (nr < itofix(-180)) nr += 360;
482  while (nr > itofix(180)) nr -= 360;
483  if (nr != Fix0)
484  if (Inside<C4Real>(nr,itofix(-StableRange),itofix(+StableRange)))
485  {
486  // Save step undos
487  C4Real lcobjr=fix_r;
488  C4Shape lshape=Shape;
489  // Try rotation
490  fix_r=Fix0;
491  UpdateShape();
492  if (ContactCheck(GetX(),GetY()))
493  { // Undo rotation
494  Shape=lshape;
495  fix_r=lcobjr;
496  }
497  else
498  { // Stabilization okay
499  UpdateFace(true);
500  }
501  }
502 }
503 
505 {
506  // Designed for contained objects, no static
507  if (fix_x != from->fix_x || fix_y != from->fix_y)
508  {
509  fix_x=from->fix_x; fix_y=from->fix_y;
510  // Resort into sectors
511  UpdatePos();
512  }
513  xdir=from->xdir; ydir=from->ydir;
514 }
515 
517 {
518  fix_x=tx; fix_y=ty;
519  UpdatePos();
520  UpdateSolidMask(false);
521 }
522 
523 void C4Object::MovePosition(int32_t dx, int32_t dy)
524 {
525  MovePosition(itofix(dx), itofix(dy));
526 }
527 
529 {
530  // move object position; repositions SolidMask
532  fix_x+=dx;
533  fix_y+=dy;
534  UpdatePos();
535  UpdateSolidMask(true);
536 }
537 
538 
539 bool C4Object::ExecMovement() // Every Tick1 by Execute
540 {
541  // update in which material this object is
542  UpdateInMat();
543 
544  // Containment check
545  if (Contained)
546  {
548 
549  return true;
550  }
551 
552  // General mobility check
553  if (Category & C4D_StaticBack) return false;
554 
555  // Movement execution
556  if (Mobile) // Object is moving
557  {
558  // Move object
559  DoMovement();
560  // Demobilization check
561  if ((xdir==0) && (ydir==0) && (rdir==0)) Mobile=0;
562  // Check for stabilization
563  if (rdir==0) Stabilize();
564  }
565  else // Object is static
566  {
567  // Check for stabilization
568  Stabilize();
569  // Check for mobilization
570  if (!::Game.iTick10)
571  {
572  // Gravity mobilization
573  xdir=ydir=rdir=0;
574  Mobile=1;
575  }
576  }
577 
578  // Enforce zero rotation
579  if (!Def->Rotateable) fix_r=Fix0;
580 
581  // Out of bounds check
582  if ((!Inside<int32_t>(GetX() + Shape.GetX(), -Shape.Wdt, ::Landscape.GetWidth()) && !(GetPropertyInt(P_BorderBound) & C4D_Border_Sides))
584  {
585  C4PropList* pActionDef = GetAction();
586  // Never remove attached objects: If they are truly outside landscape, their target will be removed,
587  // and the attached objects follow one frame later
588  if (!pActionDef || !Action.Target || pActionDef->GetPropertyP(P_Procedure) != DFA_ATTACH)
589  {
590  bool fRemove = true;
591  // never remove HUD objects
592  if (Category & C4D_Parallax)
593  {
594  int parX, parY;
595  GetParallaxity(&parX, &parY);
596  fRemove = false;
597  if (GetX()>::Landscape.GetWidth() || GetY()>::Landscape.GetHeight()) fRemove = true; // except if they are really out of the viewport to the right...
598  else if (GetX()<0 && !!parX) fRemove = true; // ...or it's not HUD horizontally and it's out to the left
599  else if (!parX && GetX()<-::Landscape.GetWidth()) fRemove = true; // ...or it's HUD horizontally and it's out to the left
600  }
601  if (fRemove)
602  {
603  AssignDeath(true);
604  AssignRemoval();
605  }
606  }
607  }
608  return true;
609 }
610 
611 bool SimFlight(C4Real &x, C4Real &y, C4Real &xdir, C4Real &ydir, int32_t iDensityMin, int32_t iDensityMax, int32_t &iIter)
612 {
613  bool hitOnTime = true;
614  bool fBreak = false;
615  int32_t ctcox,ctcoy,cx,cy,i;
616  cx = fixtoi(x); cy = fixtoi(y);
617  i = iIter;
618  do
619  {
620  if (!--i) {hitOnTime = false; break;}
621  // If the object isn't moving and there is no gravity either, abort
622  if (xdir == 0 && ydir == 0 && GravAccel == 0)
623  return false;
624  // If the object is above the landscape flying upwards in no/negative gravity, abort
625  if (ydir <= 0 && GravAccel <= 0 && cy < 0)
626  return false;
627  // Set target position by momentum
628  x+=xdir; y+=ydir;
629  // Movement to target
630  ctcox=fixtoi(x); ctcoy=fixtoi(y);
631  // Bounds
632  if (!Inside<int32_t>(ctcox,0,::Landscape.GetWidth()) || (ctcoy>=::Landscape.GetHeight()))
633  return false;
634  // Move to target
635  do
636  {
637  // Set next step target
638  cx+=Sign(ctcox-cx); cy+=Sign(ctcoy-cy);
639  // Contact check
640  if (Inside(GBackDensity(cx,cy), iDensityMin, iDensityMax))
641  { fBreak = true; break; }
642  }
643  while ((cx!=ctcox) || (cy!=ctcoy));
644  // Adjust GravAccel once per frame
645  ydir+=GravAccel;
646  }
647  while (!fBreak);
648  // write position back
649  x = itofix(cx); y = itofix(cy);
650 
651  // how many steps did it take to get here?
652  iIter -= i;
653 
654  return hitOnTime;
655 }
656 
657 bool SimFlightHitsLiquid(C4Real fcx, C4Real fcy, C4Real xdir, C4Real ydir)
658 {
659  // Start in water?
660  int temp;
661  if (DensityLiquid(GBackDensity(fixtoi(fcx), fixtoi(fcy))))
662  if (!SimFlight(fcx, fcy, xdir, ydir, 0, C4M_Liquid - 1, temp=10))
663  return false;
664  // Hits liquid?
665  if (!SimFlight(fcx, fcy, xdir, ydir, C4M_Liquid, 100, temp=-1))
666  return false;
667  // liquid & deep enough?
668  return GBackLiquid(fixtoi(fcx), fixtoi(fcy)) && GBackLiquid(fixtoi(fcx), fixtoi(fcy) + 9);
669 }
670 
C4PropertyName GetPropertyP(C4PropertyName k) const
Definition: C4PropList.cpp:810
int32_t GetY() const
Definition: C4Object.h:287
const uint32_t OCF_HitSpeed1
Definition: C4Constants.h:84
const C4Real FFriction
Definition: C4Movement.cpp:33
#define PSF_Hit
Definition: C4GameScript.h:49
void MovePosition(int32_t dx, int32_t dy)
Definition: C4Movement.cpp:523
void ForcePosition(C4Real tx, C4Real ty)
Definition: C4Movement.cpp:516
C4Game Game
Definition: C4Globals.cpp:52
int32_t GetY() const
Definition: C4Shape.h:64
const C4Real HitSpeed1
Definition: C4Movement.cpp:37
const C4Real DefaultGravAccel
Definition: C4Movement.cpp:41
bool Alive
Definition: C4Object.h:175
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)
bool SimFlightHitsLiquid(C4Real fcx, C4Real fcy, C4Real xdir, C4Real ydir)
Definition: C4Movement.cpp:657
const int StableRange
Definition: C4Physics.h:25
int32_t Mass
Definition: C4Object.h:115
void Remove(bool fBackupAttachment)
void AssignDeath(bool fForced)
Definition: C4Object.cpp:1004
C4PropList * GetAction() const
Definition: C4Object.cpp:2689
int32_t ContactCheck(int32_t atx, int32_t aty, uint32_t *border_hack_contacts=0, bool collide_halfvehic=false)
Definition: C4Movement.cpp:137
C4Real rdir
Definition: C4Object.h:126
const int32_t C4D_Border_Sides
Definition: C4Def.h:67
#define GravAccel
Definition: C4Physics.h:29
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)
C4Real C4REAL100(int x)
Definition: C4Real.h:267
uint8_t BYTE
int Sign(T val)
Definition: Standard.h:47
const int32_t C4D_Border_Top
Definition: C4Def.h:68
C4ObjectPtr Layer
Definition: C4Object.h:136
int32_t NoHorizontalMove
Definition: C4Def.h:124
const C4Real FRedirect
Definition: C4Movement.cpp:32
Definition: C4Real.h:58
bool Mobile
Definition: C4Object.h:128
const int32_t FullCon
Definition: C4Constants.h:182
int32_t ContactCount
Definition: C4Shape.h:50
void UpdatePos()
Definition: C4Object.cpp:373
int32_t Rotateable
Definition: C4Def.h:121
int32_t VtxFriction[C4D_MaxVertex]
Definition: C4Shape.h:47
const char * CNATName(int32_t cnat)
Definition: C4Movement.cpp:101
int32_t Wdt
Definition: C4Rect.h:32
bool InLiquid
Definition: C4Object.h:131
const uint32_t OCF_HitSpeed2
Definition: C4Constants.h:91
void SideBounds(C4Real &ctcox)
Definition: C4Movement.cpp:157
const int32_t C4D_Border_Bottom
Definition: C4Def.h:69
const C4Real FloatFriction
Definition: C4Movement.cpp:35
C4Def * Def
Definition: C4Object.h:143
int32_t t_attach
Definition: C4Object.h:86
void ApplyFriction(C4Real &tval, int32_t percent)
Definition: C4Movement.cpp:53
void RedirectForce(C4Real &from, C4Real &to, int32_t tdir)
Definition: C4Movement.cpp:45
void UpdateShape(bool bUpdateVertices=true)
Definition: C4Object.cpp:346
#define PSF_Hit2
Definition: C4GameScript.h:50
uint32_t t_contact
Definition: C4Object.h:133
int32_t ContactVtxFriction(C4Object *cobj)
Definition: C4Movement.cpp:92
bool DensityLiquid(int32_t dens)
Definition: C4Landscape.h:209
C4Landscape Landscape
void DoMovement()
Definition: C4Movement.cpp:203
void ContactAction()
Definition: C4Object.cpp:2932
int32_t VtxContactCNAT[C4D_MaxVertex]
Definition: C4Shape.h:52
void NoAttachAction()
Definition: C4Object.cpp:2897
int32_t ContactCNAT
Definition: C4Shape.h:49
int32_t Con
Definition: C4Object.h:173
int32_t GetX() const
Definition: C4Shape.h:63
int32_t VtxNum
Definition: C4Shape.h:43
int32_t GetX() const
Definition: C4Object.h:286
void AssignRemoval(bool fExitContents=false)
Definition: C4Object.cpp:257
int32_t VtxX[C4D_MaxVertex]
Definition: C4Shape.h:44
C4Fixed itofix(int32_t x)
Definition: C4Real.h:261
const C4Real FixFullCircle
Definition: C4Movement.cpp:34
const int32_t C4D_StaticBack
Definition: C4Def.h:42
const uint32_t OCF_Rotate
Definition: C4Constants.h:88
int32_t iTick10
Definition: C4Game.h:131
void UpdateFace(bool bUpdateShape, bool fTemp=false)
Definition: C4Object.cpp:381
bool IsInLiquidCheck() const
Definition: C4Object.cpp:4116
int32_t Category
Definition: C4Object.h:113
void VerticalBounds(C4Real &ctcoy)
Definition: C4Movement.cpp:180
void CopyMotion(C4Object *from)
Definition: C4Movement.cpp:504
int32_t GetHeight() const
bool ExecMovement()
Definition: C4Movement.cpp:539
C4ObjectPtr Target
Definition: C4Object.h:87
const BYTE CNAT_None
Definition: C4Constants.h:109
int32_t ContactVtxWeight(C4Object *cobj)
Definition: C4Movement.cpp:77
C4Real fix_r
Definition: C4Object.h:125
C4Real fix_x
Definition: C4Object.h:125
const BYTE CNAT_Top
Definition: C4Constants.h:112
void GetParallaxity(int32_t *parX, int32_t *parY) const
Definition: C4Object.cpp:4281
const int32_t C4D_Border_Layer
Definition: C4Def.h:70
int32_t GBackDensity(int32_t x, int32_t y)
Definition: C4Landscape.h:227
const C4Real RotateAccel
Definition: C4Movement.cpp:36
#define PSF_Contact
Definition: C4GameScript.h:69
const BYTE CNAT_Right
Definition: C4Constants.h:111
int32_t NoStabilize
Definition: C4Def.h:140
const C4Real HitSpeed3
Definition: C4Movement.cpp:39
#define PSF_Hit3
Definition: C4GameScript.h:51
const uint32_t OCF_HitSpeed3
Definition: C4Constants.h:92
void Stabilize()
Definition: C4Movement.cpp:475
int32_t GetPropertyInt(C4PropertyName k, int32_t default_val=0) const
Definition: C4PropList.cpp:841
bool SimFlight(C4Real &x, C4Real &y, C4Real &xdir, C4Real &ydir, int32_t iDensityMin, int32_t iDensityMax, int32_t &iIter)
Definition: C4Movement.cpp:611
const int32_t C4D_Parallax
Definition: C4Def.h:53
C4Real fix_y
Definition: C4Object.h:125
C4ObjectPtr Contained
Definition: C4Object.h:144
int32_t Hgt
Definition: C4Rect.h:32
const C4Real HitSpeed4
Definition: C4Movement.cpp:40
T Abs(T val)
Definition: Standard.h:44
const C4Real HitSpeed2
Definition: C4Movement.cpp:38
C4Action Action
Definition: C4Object.h:147
C4Shape Shape
Definition: C4Object.h:148
const int32_t C4M_Liquid
Definition: C4Constants.h:175
uint32_t OCF
Definition: C4Object.h:134
C4Value Call(C4PropertyName k, C4AulParSet *pPars=0, bool fPassErrors=false)
Definition: C4PropList.h:112
void UpdateSolidMask(bool fRestoreAttachedObjects)
Definition: C4Object.cpp:4156
bool ContactVtxCNAT(C4Object *cobj, BYTE cnat_dir)
Definition: C4Movement.cpp:64
C4SolidMask * pSolidMaskData
Definition: C4Object.h:176
int fixtoi(const C4Fixed &x)
Definition: C4Real.h:259
C4Real xdir
Definition: C4Object.h:126
const C4Real FixHalfCircle
Definition: C4Movement.cpp:34
bool Inside(T ival, U lbound, V rbound)
Definition: Standard.h:45
void StopAndContact(C4Real &ctco, C4Real limit, C4Real &speed, int32_t cnat)
Definition: C4Movement.cpp:130
const BYTE CNAT_Left
Definition: C4Constants.h:110
const BYTE CNAT_Bottom
Definition: C4Constants.h:113
bool Attach(int32_t &cx, int32_t &cy, BYTE cnat_pos)
Definition: C4Shape.cpp:185
C4Real ydir
Definition: C4Object.h:126
bool GBackLiquid(int32_t x, int32_t y)
Definition: C4Landscape.h:242
int32_t GetWidth() const
void DoMotion(int32_t mx, int32_t my)
Definition: C4Movement.cpp:124
bool Contact(int32_t cnat)
Definition: C4Movement.cpp:115
const C4Real Fix0
Definition: C4Real.h:312
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:277
bool ContactCheck(int32_t cx, int32_t cy, uint32_t *border_hack_contacts=0, bool collide_halfvehic=false)
Definition: C4Shape.cpp:352
const BYTE CNAT_Center
Definition: C4Constants.h:114