OpenClonk
C4Shape.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 /* Basic classes for rectangles and vertex outlines */
19 
20 #include "C4Include.h"
21 #include "object/C4Shape.h"
22 
23 #include "control/C4Record.h"
24 #include "game/C4Physics.h"
25 #include "landscape/C4Landscape.h"
26 #include "landscape/C4Material.h"
27 
28 bool C4Shape::AddVertex(int32_t iX, int32_t iY)
29 {
30  if (VtxNum >= C4D_MaxVertex)
31  {
32  return false;
33  }
34  VtxX[VtxNum] = iX;
35  VtxY[VtxNum] = iY;
36  VtxNum++;
37  return true;
38 }
39 
41 {
42  InplaceReconstruct(this);
43 }
44 
45 void C4Shape::Rotate(C4Real angle, bool update_vertices)
46 {
48  {
49  C4RCRotVtx rc;
50  rc.x = x;
51  rc.y = y;
52  rc.wdt = Wdt;
53  rc.hgt = Hgt;
54  rc.r = fixtoi(angle);
55  for (int32_t i = 0; i < 4; ++i)
56  {
57  rc.VtxX[i] = VtxX[i];
58  rc.VtxY[i] = VtxY[i];
59  }
60  AddDbgRec(RCT_RotVtx1, &rc, sizeof(rc));
61  }
62 
63  // Calculate rotation matrix
64  C4Real rot_matrix[4];
65  rot_matrix[0] = Cos(angle); rot_matrix[1] = -Sin(angle);
66  rot_matrix[2] = -rot_matrix[1]; rot_matrix[3] = rot_matrix[0];
67 
68  if (update_vertices)
69  {
70  // Rotate vertices
71  for (int32_t cnt = 0; cnt < VtxNum; cnt++)
72  {
73  int32_t old_x = VtxX[cnt];
74  int32_t old_y = VtxY[cnt];
75  VtxX[cnt] = fixtoi(rot_matrix[0] * old_x + rot_matrix[1] * old_y);
76  VtxY[cnt] = fixtoi(rot_matrix[2] * old_x + rot_matrix[3] * old_y);
77  }
78  }
79 
80  // Enlarge Rect
81  int32_t new_x = fixtoi(rot_matrix[0] * x + rot_matrix[1] * y);
82  int32_t new_y = fixtoi(rot_matrix[2] * x + rot_matrix[3] * y);
83  int32_t new_wdt = 0;
84  int32_t new_hgt = 0;
85  if (rot_matrix[0] > 0)
86  {
87  if (rot_matrix[1] > 0)
88  {
89  new_wdt = fixtoi(rot_matrix[0] * Wdt + rot_matrix[1] * Hgt);
90  new_hgt = fixtoi(rot_matrix[1] * Wdt + rot_matrix[0] * Hgt);
91  x = new_x;
92  y = new_y - fixtoi(rot_matrix[1] * Wdt);
93  }
94  else
95  {
96  new_wdt = fixtoi(rot_matrix[0] * Wdt - rot_matrix[1] * Hgt);
97  new_hgt = fixtoi(- rot_matrix[1] * Wdt + rot_matrix[0] * Hgt);
98  x = new_x + fixtoi(rot_matrix[1] * Hgt);
99  y = new_y;
100  }
101  }
102  else
103  {
104  if (rot_matrix[1] > 0)
105  {
106  new_wdt = fixtoi(- rot_matrix[0] * Wdt + rot_matrix[1] * Hgt);
107  new_hgt = fixtoi(rot_matrix[1] * Wdt - rot_matrix[0] * Hgt);
108  x = new_x + fixtoi(rot_matrix[0] * Wdt);
109  y = new_y - new_hgt;
110  }
111  else
112  {
113  new_wdt = fixtoi(- rot_matrix[0] * Wdt - rot_matrix[1] * Hgt);
114  new_hgt = fixtoi(- rot_matrix[1] * Wdt - rot_matrix[0] * Hgt);
115  x = new_x - new_wdt;
116  y = new_y + fixtoi(rot_matrix[0] * Hgt);
117  }
118  }
119  Wdt = new_wdt;
120  Hgt = new_hgt;
121  if (Config.General.DebugRec)
122  {
123  C4RCRotVtx rc;
124  rc.x = x;
125  rc.y = y;
126  rc.wdt = Wdt;
127  rc.hgt = Hgt;
128  for (int32_t i = 0; i < 4; ++i)
129  {
130  rc.VtxX[i] = VtxX[i];
131  rc.VtxY[i] = VtxY[i];
132  }
133  AddDbgRec(RCT_RotVtx2, &rc, sizeof(rc));
134  }
135 }
136 
137 static inline int32_t ScaledByCon(int32_t value, int32_t con)
138 {
139  return value * con / FullCon;
140 }
141 
142 void C4Shape::Stretch(int32_t iCon, bool update_vertices)
143 {
144  x = ScaledByCon(x, iCon);
145  y = ScaledByCon(y, iCon);
146  Wdt = ScaledByCon(Wdt, iCon);
147  Hgt = ScaledByCon(Hgt, iCon);
148  if (update_vertices)
149  {
150  for (int32_t i = 0; i < VtxNum; i++)
151  {
152  VtxX[i] = ScaledByCon(VtxX[i], iCon);
153  VtxY[i] = ScaledByCon(VtxY[i], iCon);
154  }
155  }
156 }
157 
158 void C4Shape::Jolt(int32_t iCon, bool update_vertices)
159 {
160  y = ScaledByCon(y, iCon);
161  Hgt = ScaledByCon(Hgt, iCon);
162  if (update_vertices)
163  {
164  for (int32_t i = 0; i < VtxNum; i++)
165  {
166  VtxY[i] = ScaledByCon(VtxY[i], iCon);
167  }
168  }
169 }
170 
172 {
173  rRect.x = 0;
174  rRect.y = 0;
175  rRect.Wdt = 0;
176  rRect.Hgt = 0;
177  for (int32_t i = 0; i < VtxNum; i++)
178  {
179  // Extend left
180  if (VtxX[i] < rRect.x)
181  {
182  rRect.Wdt += rRect.x - VtxX[i];
183  rRect.x = VtxX[i];
184  }
185  // Extend right
186  else if (VtxX[i] > rRect.x + rRect.Wdt)
187  {
188  rRect.Wdt = VtxX[i] - rRect.x;
189  }
190  // Extend up
191  if (VtxY[i] < rRect.y)
192  {
193  rRect.Hgt += rRect.y - VtxY[i];
194  rRect.y = VtxY[i];
195  }
196  // Extend down
197  else if (VtxY[i] > rRect.y + rRect.Hgt)
198  {
199  rRect.Hgt = VtxY[i] - rRect.y;
200  }
201  }
202 
203  rRect.Hgt += rRect.y - y;
204  rRect.y = y;
205 }
206 
207 inline bool C4Shape::CheckTouchableMaterial(int32_t x, int32_t y, int32_t vtx_i, int32_t ydir, const C4DensityProvider &rDensityProvider)
208 {
209  return rDensityProvider.GetDensity(x, y) >= ContactDensity
210  && ((ydir > 0 && !(CNAT_PhaseHalfVehicle & VtxCNAT[vtx_i])) || !IsMCHalfVehicle(::Landscape.GetPix(x, y)));
211 }
212 
213 // Adjust given position to one pixel before contact
214 // at vertices matching CNAT request.
215 bool C4Shape::Attach(int32_t &cx, int32_t &cy, BYTE cnat_pos)
216 {
217  // Reset attached material
218  AttachMat = MNone;
219  int xcd = 0;
220  int ycd = 0;
221  // Determine attachment direction
222  switch (cnat_pos & (~CNAT_Flags))
223  {
224  case CNAT_Top:
225  ycd = -1;
226  break;
227  case CNAT_Bottom:
228  ycd = +1;
229  break;
230  case CNAT_Left:
231  xcd = -1;
232  break;
233  case CNAT_Right:
234  xcd = +1;
235  break;
236  default:
237  return false;
238  }
239  int testx = cx;
240  int testy = cy;
241  bool increase_distance = true;
242  bool any_contact = false;
243 
244  // Find the nearest position that has at least one vertex adjacent to dense material
245  // and no vertices in dense materials
246  while (Abs(testx - cx) < AttachRange && Abs(testy - cy) < AttachRange)
247  {
248  bool found = false;
249  for (int i = 0; i < VtxNum; ++i)
250  {
251  if (VtxCNAT[i] & cnat_pos)
252  {
253  // Get new vertex pos
254  int32_t ax = testx + VtxX[i];
255  int32_t ay = testy + VtxY[i];
256  if (CheckTouchableMaterial(ax, ay, i))
257  {
258  found = false;
259  break;
260  }
261  // Can attach here?
262  if (CheckTouchableMaterial(ax + xcd, ay + ycd, i, ycd))
263  {
264  found = true;
265  any_contact = true;
266  // Store attachment material
267  AttachMat = GBackMat(ax + xcd, ay + ycd);
268  // Store absolute attachment position
269  iAttachX = ax + xcd;
270  iAttachY = ay + ycd;
271  iAttachVtx = i;
272  }
273  }
274  }
275  if (found)
276  {
277  cx = testx;
278  cy = testy;
279  return true;
280  }
281  // Try positions in order of distance from the origin,
282  // and alternating the direction
283  testx = cx - (testx - cx);
284  testy = cy - (testy - cy);
285  if (increase_distance)
286  {
287  testx += xcd;
288  testy += ycd;
289  }
290  increase_distance = !increase_distance;
291  }
292  return any_contact;
293 }
294 
295 bool C4Shape::LineConnect(int32_t tx, int32_t ty, int32_t cvtx, int32_t ld, int32_t oldx, int32_t oldy)
296 {
297  // Lines require at least 2 vertices
298  if (VtxNum < 2)
299  {
300  return false;
301  }
302 
303  // No modification
304  if ((VtxX[cvtx] == tx) && (VtxY[cvtx] == ty))
305  {
306  return true;
307  }
308 
309  // Check new path
310  int32_t ix;
311  int32_t iy;
312  if (PathFree(tx, ty, VtxX[cvtx + ld], VtxY[cvtx + ld], &ix, &iy))
313  {
314  // Okay, set vertex
315  VtxX[cvtx] = tx;
316  VtxY[cvtx] = ty;
317  return true;
318  }
319  else
320  {
321  // Intersected, find bend vertex
322  bool found = false;
323  int32_t cix;
324  int32_t ciy;
325  for (int irange = 4; irange <= 12; irange += 4)
326  {
327  for (cix = ix - irange / 2; cix <= ix + irange; cix += irange)
328  {
329  for (ciy = iy - irange / 2; ciy <= iy + irange; ciy += irange)
330  {
331  if (PathFree(cix, ciy, tx, ty) && PathFree(cix, ciy, VtxX[cvtx + ld], VtxY[cvtx + ld]))
332  {
333  found = true;
334  goto out;
335  }
336  }
337  }
338  }
339 out:
340  if (!found)
341  {
342  // Try bending directly at path the line took
343  // Allow going through vehicle in this case to allow lines through castles and elevator shafts
344  cix = oldx;
345  ciy = oldy;
346  if (!PathFreeIgnoreVehicle(cix, ciy, tx, ty) || !PathFreeIgnoreVehicle(cix, ciy, VtxX[cvtx + ld], VtxY[cvtx + ld]))
347  {
348  return false; // Found no bend vertex
349  }
350  }
351  // Insert bend vertex
352  if (ld > 0)
353  {
354  if (!InsertVertex(cvtx + 1, cix, ciy))
355  {
356  return false;
357  }
358  }
359  else
360  {
361  if (!InsertVertex(cvtx, cix, ciy))
362  {
363  return false;
364  }
365  cvtx++;
366  }
367  // Okay, set vertex
368  VtxX[cvtx] = tx;
369  VtxY[cvtx] = ty;
370  return true;
371  }
372 
373  return false;
374 }
375 
376 bool C4Shape::InsertVertex(int32_t index_position, int32_t tx, int32_t ty)
377 {
378  if (VtxNum + 1 > C4D_MaxVertex)
379  {
380  return false;
381  }
382  if (!Inside<int32_t>(index_position, 0, VtxNum))
383  {
384  return false;
385  }
386  // Insert vertex before iPos
387  for (int32_t i = VtxNum; i > index_position; i--)
388  {
389  VtxX[i] = VtxX[i - 1];
390  VtxY[i] = VtxY[i - 1];
391  }
392  VtxX[index_position] = tx;
393  VtxY[index_position] = ty;
394  VtxNum++;
395  return true;
396 }
397 
398 bool C4Shape::RemoveVertex(int32_t index_position)
399 {
400  if (!Inside<int32_t>(index_position, 0, VtxNum - 1))
401  {
402  return false;
403  }
404  for (int32_t i = index_position; i + 1 < VtxNum; i++)
405  {
406  VtxX[i] = VtxX[i + 1];
407  VtxY[i] = VtxY[i + 1];
408  }
409  VtxNum--;
410  return true;
411 }
412 
413 bool C4Shape::CheckContact(int32_t at_x, int32_t at_y)
414 {
415  // Check all vertices at given object position.
416  // Return true on any contact.
417 
418  for (int32_t i = 0; i < VtxNum; i++)
419  {
420  if (!(VtxCNAT[i] & CNAT_NoCollision))
421  {
422  if (CheckTouchableMaterial(at_x + VtxX[i], at_y + VtxY[i], i))
423  {
424  return true;
425  }
426  }
427  }
428 
429  return false;
430 }
431 
432 bool C4Shape::ContactCheck(int32_t at_x, int32_t at_y, uint32_t *border_hack_contacts, bool collide_halfvehic)
433 {
434  // Check all vertices at given object position.
435  // Set ContactCNAT and ContactCount.
436  // Set VtxContactCNAT and VtxContactMat.
437  // Return true on any contact.
438 
440  ContactCount = 0;
441 
442  for (int32_t vertex = 0; vertex < VtxNum; vertex++)
443  {
444  // Ignore vertex if collision has been flagged out
445  if (!(VtxCNAT[vertex] & CNAT_NoCollision))
446  {
447  VtxContactCNAT[vertex] = CNAT_None;
448  int32_t x = at_x + VtxX[vertex];
449  int32_t y = at_y + VtxY[vertex];
450  VtxContactMat[vertex] = GBackMat(x, y);
451 
452  if (CheckTouchableMaterial(x, y, vertex, collide_halfvehic? 1:0))
453  {
454  ContactCNAT |= VtxCNAT[vertex];
455  VtxContactCNAT[vertex] |= CNAT_Center;
456  ContactCount++;
457  // Vertex center contact, now check top, bottom, left, right
458  // Not using our style guideline here, is more readable in "table" format
459  if (CheckTouchableMaterial(x, y - 1, vertex, collide_halfvehic ? 1 : 0)) VtxContactCNAT[vertex] |= CNAT_Top;
460  if (CheckTouchableMaterial(x, y + 1, vertex, collide_halfvehic ? 1 : 0)) VtxContactCNAT[vertex] |= CNAT_Bottom;
461  if (CheckTouchableMaterial(x - 1, y, vertex, collide_halfvehic ? 1 : 0)) VtxContactCNAT[vertex] |= CNAT_Left;
462  if (CheckTouchableMaterial(x + 1, y, vertex, collide_halfvehic ? 1 : 0)) VtxContactCNAT[vertex] |= CNAT_Right;
463  }
464  if (border_hack_contacts)
465  {
466  if (x == 0 && CheckTouchableMaterial(x - 1, y, vertex))
467  {
468  *border_hack_contacts |= CNAT_Left;
469  }
470  else if (x == ::Landscape.GetWidth() && CheckTouchableMaterial(x + 1, y, vertex))
471  {
472  *border_hack_contacts |= CNAT_Right;
473  }
474  }
475  }
476  }
477 
478 
479  return !!ContactCount;
480 }
481 
482 bool C4Shape::CheckScaleToWalk(int x, int y)
483 {
484  for (int32_t i = 0; i < VtxNum; i++)
485  {
486  if (VtxCNAT[i] & CNAT_NoCollision)
487  {
488  continue;
489  }
490  if (VtxCNAT[i] & CNAT_Bottom)
491  {
492  // No ground under the feet?
493  if (CheckTouchableMaterial(x + VtxX[i], y + VtxY[i] + 1, i))
494  {
495  return false;
496  }
497  }
498  else
499  {
500  // Can climb with hands?
501  if (CheckTouchableMaterial(x + VtxX[i] - 1, y + VtxY[i], i))
502  {
503  return false;
504  }
505  if (CheckTouchableMaterial(x + VtxX[i] + 1, y + VtxY[i], i))
506  {
507  return false;
508  }
509  }
510  }
511  return true;
512 }
513 
514 int32_t C4Shape::GetVertexX(int32_t iVertex)
515 {
516  if (!Inside<int32_t>(iVertex, 0, VtxNum - 1))
517  {
518  return 0;
519  }
520  return VtxX[iVertex];
521 }
522 
523 int32_t C4Shape::GetVertexY(int32_t iVertex)
524 {
525  if (!Inside<int32_t>(iVertex, 0, VtxNum - 1))
526  {
527  return 0;
528  }
529  return VtxY[iVertex];
530 }
531 
532 void C4Shape::CopyFrom(C4Shape source, bool copy_vertices, bool copy_vertices_from_self)
533 {
534  if (copy_vertices)
535  {
536  // Truncate / copy vertex count
537  VtxNum = (copy_vertices_from_self ? std::min<int32_t>(VtxNum, C4D_VertexCpyPos) : source.VtxNum);
538 
539  // Restore vertices from back of own buffer (retaining count)
540  int32_t iCopyPos = (copy_vertices_from_self ? C4D_VertexCpyPos : 0);
541  C4Shape &vertices_from = (copy_vertices_from_self ? *this : source);
542 
543  memcpy(VtxX, vertices_from.VtxX + iCopyPos, VtxNum * sizeof(*VtxX));
544  memcpy(VtxY, vertices_from.VtxY + iCopyPos, VtxNum * sizeof(*VtxY));
545  memcpy(VtxCNAT, vertices_from.VtxCNAT + iCopyPos, VtxNum * sizeof(*VtxCNAT));
546  memcpy(VtxFriction, vertices_from.VtxFriction + iCopyPos, VtxNum * sizeof(*VtxFriction));
547  memcpy(VtxContactCNAT, vertices_from.VtxContactCNAT + iCopyPos, VtxNum * sizeof(*VtxContactCNAT));
548  memcpy(VtxContactMat, vertices_from.VtxContactMat + iCopyPos, VtxNum * sizeof(*VtxContactMat));
549  }
550 
551  // Copies other members
552  *((C4Rect *) this) = source;
553  AttachMat = source.AttachMat;
554  ContactCNAT = source.ContactCNAT;
555  ContactCount = source.ContactCount;
556 }
557 
559 {
560  // Return bottom-most vertex
561  int32_t iMax = -1;
562  for (int32_t i = 0; i < VtxNum; i++)
563  {
564  if (VtxCNAT[i] & CNAT_Bottom)
565  {
566  if (iMax == -1 || VtxY[i] < VtxY[iMax])
567  {
568  iMax = i;
569  }
570  }
571  }
572  return iMax;
573 }
574 
576 {
577  int b = INT_MIN;
578  for (int32_t i = 0; i < VtxNum; i++)
579  {
580  if (~VtxCNAT[i] & CNAT_NoCollision)
581  {
582  if (VtxY[i] > b)
583  {
584  b = VtxY[i];
585  }
586  }
587  }
588  if (b == INT_MIN)
589  {
590  return y + Hgt;
591  }
592  return b;
593 }
594 
596 
597 int32_t C4DensityProvider::GetDensity(int32_t x, int32_t y) const
598 {
599  // Default density provider checks the landscape
600  return GBackDensity(x, y);
601 }
602 
603 int32_t C4Shape::GetVertexContact(int32_t iVertex, DWORD dwCheckMask, int32_t tx, int32_t ty, const C4DensityProvider &rDensityProvider)
604 {
605  int32_t contact_bits = 0;
606 
607  // Range check
608  if (!Inside<int32_t>(iVertex, 0, VtxNum - 1))
609  {
610  return contact_bits;
611  }
612 
613  // Default check mask
614  if (!dwCheckMask)
615  {
616  dwCheckMask = VtxCNAT[iVertex];
617  }
618 
619  // Check vertex positions
620  tx += VtxX[iVertex];
621  ty += VtxY[iVertex];
622 
623  // Check all directions for solid material
624  if (~VtxCNAT[iVertex] & CNAT_NoCollision)
625  {
626  // Not using our style guideline here, is more readable in "table" format
627  if (dwCheckMask & CNAT_Center) if (CheckTouchableMaterial(tx, ty , iVertex, 0, rDensityProvider)) contact_bits |= CNAT_Center;
628  if (dwCheckMask & CNAT_Left) if (CheckTouchableMaterial(tx-1, ty, iVertex, 0, rDensityProvider)) contact_bits |= CNAT_Left;
629  if (dwCheckMask & CNAT_Right) if (CheckTouchableMaterial(tx+1, ty, iVertex, 0, rDensityProvider)) contact_bits |= CNAT_Right;
630  if (dwCheckMask & CNAT_Top) if (CheckTouchableMaterial(tx, ty-1, iVertex, 0, rDensityProvider)) contact_bits |= CNAT_Top;
631  if (dwCheckMask & CNAT_Bottom) if (CheckTouchableMaterial(tx, ty+1, iVertex, 1, rDensityProvider)) contact_bits |= CNAT_Bottom;
632  }
633  // Return resulting bitmask
634  return contact_bits;
635 }
636 
638 {
639  // Copy vertices from original buffer, including count
640  VtxNum = std::min<int32_t>(source.VtxNum, C4D_VertexCpyPos);
641  memcpy(VtxX + C4D_VertexCpyPos, source.VtxX, VtxNum * sizeof(*VtxX));
642  memcpy(VtxY + C4D_VertexCpyPos, source.VtxY, VtxNum * sizeof(*VtxY));
643  memcpy(VtxCNAT + C4D_VertexCpyPos, source.VtxCNAT, VtxNum * sizeof(*VtxCNAT));
644  memcpy(VtxFriction + C4D_VertexCpyPos, source.VtxFriction, VtxNum * sizeof(*VtxFriction));
646  memcpy(VtxContactMat + C4D_VertexCpyPos, source.VtxContactMat, VtxNum * sizeof(*VtxContactMat));
647 }
648 
649 void C4Shape::CompileFunc(StdCompiler *pComp, const C4Shape *default_shape)
650 {
651  const StdBitfieldEntry<int32_t> ContactDirections[] =
652  {
653 
654  { "CNAT_None", CNAT_None },
655  { "CNAT_Left", CNAT_Left },
656  { "CNAT_Right", CNAT_Right },
657  { "CNAT_Top", CNAT_Top },
658  { "CNAT_Bottom", CNAT_Bottom },
659  { "CNAT_Center", CNAT_Center },
660  { "CNAT_MultiAttach", CNAT_MultiAttach },
661  { "CNAT_NoCollision", CNAT_NoCollision },
662  { "CNAT_PhaseHalfVehicle", CNAT_PhaseHalfVehicle },
663 
664  { nullptr, 0 }
665  };
666 
667  // A default shape is given in object compilation context only
668  bool fRuntime = !!default_shape;
669  C4Shape default_def_shape;
670  if (!default_shape)
671  {
672  default_shape = &default_def_shape;
673  }
674  // Note: Compiled directly into "Object" and "DefCore"-categories, so beware of name clashes
675  // (see C4Object::CompileFunc and C4Def::CompileFunc)
676  pComp->Value(mkNamingAdapt( Wdt, "Width", default_shape->Wdt));
677  pComp->Value(mkNamingAdapt( Hgt, "Height", default_shape->Hgt));
678  pComp->Value(mkNamingAdapt( mkArrayAdaptDefArr(&x,2,&default_shape->x), "Offset", &default_shape->x));
679  pComp->Value(mkNamingAdapt( VtxNum, "Vertices", default_shape->VtxNum));
680  pComp->Value(mkNamingAdapt( mkArrayAdaptDMA(VtxX, default_shape->VtxX), "VertexX", default_shape->VtxX));
681  pComp->Value(mkNamingAdapt( mkArrayAdaptDMA(VtxY, default_shape->VtxY), "VertexY", default_shape->VtxY));
682  pComp->Value(mkNamingAdapt( mkArrayAdaptDMAM(VtxCNAT, default_shape->VtxCNAT, [&](decltype(*VtxCNAT) &elem){ return mkBitfieldAdapt<int32_t>(elem, ContactDirections); }), "VertexCNAT", default_shape->VtxCNAT));
683  pComp->Value(mkNamingAdapt( mkArrayAdaptDMA(VtxFriction, default_shape->VtxFriction), "VertexFriction", default_shape->VtxFriction));
684  pComp->Value(mkNamingAdapt( ContactDensity, "ContactDensity", default_shape->ContactDensity));
685  if (fRuntime)
686  {
687  pComp->Value(mkNamingAdapt( iAttachX, "AttachX", 0 ));
688  pComp->Value(mkNamingAdapt( iAttachY, "AttachY", 0 ));
689  pComp->Value(mkNamingAdapt( iAttachVtx, "AttachVtx", 0 ));
690  }
691 }
C4Config Config
Definition: C4Config.cpp:930
const int32_t FullCon
Definition: C4Constants.h:181
const BYTE CNAT_Bottom
Definition: C4Constants.h:112
const int32_t MNone
Definition: C4Constants.h:177
const BYTE CNAT_Center
Definition: C4Constants.h:113
const BYTE CNAT_Right
Definition: C4Constants.h:110
const BYTE CNAT_Top
Definition: C4Constants.h:111
const BYTE CNAT_NoCollision
Definition: C4Constants.h:116
const BYTE CNAT_PhaseHalfVehicle
Definition: C4Constants.h:117
const BYTE CNAT_MultiAttach
Definition: C4Constants.h:115
const BYTE CNAT_Flags
Definition: C4Constants.h:119
const BYTE CNAT_None
Definition: C4Constants.h:108
const int C4D_MaxVertex
Definition: C4Constants.h:55
const BYTE CNAT_Left
Definition: C4Constants.h:109
bool PathFree(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
bool PathFreeIgnoreVehicle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t *ix, int32_t *iy)
C4Landscape Landscape
int32_t GBackMat(int32_t x, int32_t y)
Definition: C4Landscape.h:219
int32_t GBackDensity(int32_t x, int32_t y)
Definition: C4Landscape.h:224
#define b
bool IsMCHalfVehicle(BYTE mat)
Definition: C4Material.h:223
const int AttachRange
Definition: C4Physics.h:24
C4Real Cos(const C4Real &fAngle)
Definition: C4Real.h:266
int fixtoi(const C4Fixed &x)
Definition: C4Real.h:259
C4Real Sin(const C4Real &fAngle)
Definition: C4Real.h:265
void AddDbgRec(C4RecordChunkType eType, const void *pData, int iSize)
Definition: C4Record.cpp:32
@ RCT_RotVtx2
Definition: C4Record.h:66
@ RCT_RotVtx1
Definition: C4Record.h:65
int VtxX[4]
Definition: C4Record.h:165
int VtxY[4]
Definition: C4Record.h:165
#define C4D_VertexCpyPos
Definition: C4Rect.h:23
C4DensityProvider DefaultDensityProvider
Definition: C4Shape.cpp:595
uint8_t BYTE
uint32_t DWORD
T Abs(T val)
Definition: Standard.h:42
std::enable_if< std::is_nothrow_default_constructible< T >::value >::type InplaceReconstruct(T *obj)
Definition: Standard.h:35
StdArrayDefaultArrayAdapt< T, D > mkArrayAdaptDMA(T(&array)[size], const D &rDefault)
Definition: StdAdaptors.h:446
StdArrayDefaultArrayAdapt< T, D, M > mkArrayAdaptDMAM(T(&array)[size], const D &rDefault, const M &map)
Definition: StdAdaptors.h:450
StdArrayDefaultArrayAdapt< T, D > mkArrayAdaptDefArr(T *pArray, size_t iSize, const D &rDefault)
Definition: StdAdaptors.h:444
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
Definition: StdAdaptors.h:92
Definition: StdAdaptors.h:883
int32_t DebugRec
Definition: C4Config.h:63
C4ConfigGeneral General
Definition: C4Config.h:255
virtual int32_t GetDensity(int32_t x, int32_t y) const
Definition: C4Shape.cpp:597
Definition: C4Real.h:59
int32_t GetWidth() const
BYTE GetPix(int32_t x, int32_t y) const
Definition: C4Rect.h:28
int32_t y
Definition: C4Rect.h:30
int32_t Hgt
Definition: C4Rect.h:30
int32_t Wdt
Definition: C4Rect.h:30
int32_t x
Definition: C4Rect.h:30
bool AddVertex(int32_t iX, int32_t iY)
Definition: C4Shape.cpp:28
int32_t AttachMat
Definition: C4Shape.h:50
bool InsertVertex(int32_t iPos, int32_t tx, int32_t ty)
Definition: C4Shape.cpp:376
int GetBottom()
Definition: C4Shape.cpp:575
int32_t GetVertexY(int32_t iVertex)
Definition: C4Shape.cpp:523
void Stretch(int32_t iCon, bool bUpdateVertices)
Definition: C4Shape.cpp:142
int32_t VtxContactMat[C4D_MaxVertex]
Definition: C4Shape.h:52
bool CheckContact(int32_t cx, int32_t cy)
Definition: C4Shape.cpp:413
int32_t GetVertexX(int32_t iVertex)
Definition: C4Shape.cpp:514
void Jolt(int32_t iCon, bool bUpdateVertices)
Definition: C4Shape.cpp:158
void CopyFrom(C4Shape rFrom, bool bCpyVertices, bool fCopyVerticesFromSelf)
Definition: C4Shape.cpp:532
void CreateOwnOriginalCopy(C4Shape &rFrom)
Definition: C4Shape.cpp:637
bool ContactCheck(int32_t cx, int32_t cy, uint32_t *border_hack_contacts=nullptr, bool collide_halfvehic=false)
Definition: C4Shape.cpp:432
int32_t VtxCNAT[C4D_MaxVertex]
Definition: C4Shape.h:45
int32_t iAttachY
Definition: C4Shape.h:53
void GetVertexOutline(C4Rect &rRect)
Definition: C4Shape.cpp:171
int32_t iAttachX
Definition: C4Shape.h:53
int32_t VtxContactCNAT[C4D_MaxVertex]
Definition: C4Shape.h:51
int32_t ContactDensity
Definition: C4Shape.h:47
int32_t ContactCNAT
Definition: C4Shape.h:48
int32_t VtxNum
Definition: C4Shape.h:42
int32_t VtxFriction[C4D_MaxVertex]
Definition: C4Shape.h:46
int32_t iAttachVtx
Definition: C4Shape.h:53
bool RemoveVertex(int32_t iPos)
Definition: C4Shape.cpp:398
void Rotate(C4Real Angle, bool bUpdateVertices)
Definition: C4Shape.cpp:45
bool CheckScaleToWalk(int x, int y)
Definition: C4Shape.cpp:482
int32_t GetVertexContact(int32_t iVtx, DWORD dwCheckMask, int32_t tx, int32_t ty, const C4DensityProvider &rDensityProvider=DefaultDensityProvider)
Definition: C4Shape.cpp:603
int32_t VtxY[C4D_MaxVertex]
Definition: C4Shape.h:44
int32_t ContactCount
Definition: C4Shape.h:49
void CompileFunc(StdCompiler *pComp, const C4Shape *default_shape)
Definition: C4Shape.cpp:649
void Default()
Definition: C4Shape.cpp:40
bool Attach(int32_t &cx, int32_t &cy, BYTE cnat_pos)
Definition: C4Shape.cpp:215
int32_t VtxX[C4D_MaxVertex]
Definition: C4Shape.h:43
int32_t GetBottomVertex()
Definition: C4Shape.cpp:558
bool LineConnect(int32_t tx, int32_t ty, int32_t cvtx, int32_t ld, int32_t oldx, int32_t oldy)
Definition: C4Shape.cpp:295
void Value(const T &rStruct)
Definition: StdCompiler.h:161