OpenClonk
C4PathFinder.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 /* Finds the way through the Clonk landscape */
19 
20 /* Notes
21 
22  09-30-99
23  I have had the concept for this code for more than two years now.
24  Finally, it is written.
25 
26  10-26-99
27  C4PathFinderRay::Crawl use IsCrawlAttach instead of GetCrawlAttach (which
28  might not correctly indicate attach loss). Otherwise 1 pixel clefts can lead
29  to backward crawl looping. Surprised, I haven't noticed this before.
30  Also do not check attach loss on first crawl for that be might diagonal.
31  C4PF_Ray_Crawl try new ray: don't worry about checking backwards jump if
32  path to target is all free.
33  C4PathFinderRay::FindCrawlAttachDiagonal check according to desired
34  direction or else might lead off to no attach.
35 
36  11-24-99
37  TransferZones
38 
39  12-11-99
40  SetCompletePath don't set move-to waypoint if setting use-zone waypoint (is
41  done by C4Command::Transfer on demand and would only cause no-good-entry-point
42  move-to's on crawl-zone-entries).
43 
44 */
45 
46 #include "C4Include.h"
47 #include "landscape/C4PathFinder.h"
48 
49 #include "game/C4GraphicsSystem.h"
50 #include "graphics/C4Draw.h"
51 #include "graphics/C4FacetEx.h"
52 #include "lib/StdColors.h"
53 
54 const int32_t C4PF_MaxDepth = 35,
56  C4PF_MaxRay = 350,
60 // C4PF_Direction_None = 0,
72 
73 //------------------------------- C4PathFinderRay ---------------------------------------------
75 {
76  friend class C4PathFinder;
77 public:
80 public:
81  void Clear();
82  void Default();
83 protected:
84  int32_t Status;
85  int32_t X, Y, X2, Y2, TargetX, TargetY;
87  int32_t Direction, Depth;
92 protected:
93  void SetCompletePath();
94  void TurnAttach(int32_t &rAttach, int32_t iDirection);
95  void CrawlToAttach(int32_t &rX, int32_t &rY, int32_t iAttach);
96  void CrawlByAttach(int32_t &rX, int32_t &rY, int32_t iAttach, int32_t iDirection);
97  void Draw(C4TargetFacet &cgo);
98  int32_t FindCrawlAttachDiagonal(int32_t iX, int32_t iY, int32_t iDirection);
99  int32_t FindCrawlAttach(int32_t iX, int32_t iY);
100  bool IsCrawlAttach(int32_t iX, int32_t iY, int32_t iAttach);
101  bool CheckBackRayShorten();
102  bool Execute();
103  bool CrawlTargetFree(int32_t iX, int32_t iY, int32_t iAttach, int32_t iDirection);
104  bool PointFree(int32_t iX, int32_t iY);
105  bool Crawl();
106  bool PathFree(int32_t &rX, int32_t &rY, int32_t iToX, int32_t iToY, C4TransferZone **ppZone = nullptr);
107 };
108 
110 {
111  Default();
112 }
113 
115 {
116  Clear();
117 }
118 
120 {
122  X=Y=X2=Y2=TargetX=TargetY=0;
123  Direction=0;
124  Depth=0;
125  UseZone=nullptr;
126  From=nullptr;
127  Next=nullptr;
128  pPathFinder=nullptr;
130 }
131 
133 {
134 
135 }
136 
138 {
139  C4TransferZone *pZone = nullptr;
140  int32_t iX,iY,iLastX,iLastY;
141  switch (Status)
142  {
143  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
144  case C4PF_Ray_Launch:
145  // In zone: use zone
146  if (UseZone)
147  {
148  // Mark zone used
149  UseZone->Used=true;
150  // Target in transfer zone: success
151  if (UseZone->At(TargetX,TargetY))
152  {
153  // Set end point
154  X2=TargetX; Y2=TargetY;
155  // Set complete path
156  SetCompletePath();
157  // Done
158  pPathFinder->Success=true;
160  }
161  // Continue from other end of zone
162  else
163  {
164  // Find exit point
166  { Status=C4PF_Ray_Failure; break; }
167  // Launch new ray (continue direction of entrance ray)
168  if (!pPathFinder->AddRay(X2,Y2,TargetX,TargetY,Depth+1,Direction,this))
169  { Status=C4PF_Ray_Failure; break; }
170  // Still
172  }
173  return true;
174  }
175  // Not in zone: check path to target
176  // Path free: success
177  else if (PathFree(X2,Y2,TargetX,TargetY,&pZone))
178  {
179  // Set complete path
180  SetCompletePath();
181  // Done
182  pPathFinder->Success=true;
184  return true;
185  }
186  // Path intersected by transfer zone
187  else if (pZone)
188  {
189  // Zone entry point adjust (if not already in zone)
190  if (!pZone->At(X,Y))
191  pZone->GetEntryPoint(X2,Y2,X2,Y2);
192  // Add use-zone ray
193  if (!pPathFinder->AddRay(X2,Y2,TargetX,TargetY,Depth+1,Direction,this,pZone))
194  { Status=C4PF_Ray_Failure; break; }
195  // Still
197  // Continue
198  return true;
199  }
200  // Path intersected by solid
201  else
202  {
203  // Start crawling
207  CrawlLength=0;
210  // Intersected but no attach found: unexpected failure
211  if (!CrawlAttach) { Status=C4PF_Ray_Failure; break; }
212  // Continue
213  return true;
214  }
215  break;
216  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
217  case C4PF_Ray_Crawl:
218  // Crawl
219  iLastX=X2; iLastY=Y2;
220  if (!Crawl())
221  { Status=C4PF_Ray_Failure; break; }
222  // Back at crawl starting position: done and still
224  { Status=C4PF_Ray_Still; break; }
225  // Check unused zone intersection
226  if (pPathFinder->TransferZonesEnabled)
227  if (pPathFinder->TransferZones)
228  if ((pZone = pPathFinder->TransferZones->Find(X2,Y2)))
229  if (!pZone->Used)
230  {
231  // Add use-zone ray (with zone entry point adjust)
232  iX=X2; iY=Y2; if (pZone->GetEntryPoint(iX,iY,X2,Y2))
233  if (!pPathFinder->AddRay(iX,iY,TargetX,TargetY,Depth+1,Direction,this,pZone))
234  { Status=C4PF_Ray_Failure; break; }
235  // Continue crawling
236  return true;
237  }
238  // Crawl length
239  CrawlLength++;
240  if (CrawlLength >= C4PF_MaxCrawl * pPathFinder->Level)
241  { Status=C4PF_Ray_Still; break; }
242  // Check back path intersection
243  iX=X; iY=Y;
244  if (!PathFree(iX,iY,X2,Y2))
245  // Insert split ray
246  if (!pPathFinder->SplitRay(this,iLastX,iLastY))
247  { Status=C4PF_Ray_Failure; break; }
248  // Try new ray at target
249  iX=X2; iY=Y2;
250  // If has been crawling for a while
252  // If all free...
253  if ( PathFree(iX,iY,TargetX,TargetY)
254  // ...or at least beyond threshold and not backwards toward crawl start
256  {
257  // Still
259  // Launch new rays
262  { Status=C4PF_Ray_Failure; break; }
263  }
264  break;
265  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
267  return false;
268  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
269  }
270  return true;
271 }
272 
274 {
275  uint32_t Color=0xffff0000;
276  switch (Status)
277  {
278  case C4PF_Ray_Crawl: Color=C4RGB(0xff, 0, 0); break;
279  case C4PF_Ray_Still: Color=C4RGB(0x50, 0, 0); break;
280  case C4PF_Ray_Failure: Color=C4RGB(0xff, 0xff, 0); break;
281  case C4PF_Ray_Deleted: Color=C4RGB(0x59, 0x59, 0x59); break;
282  }
283  if (UseZone) Color=C4RGB(0, 0, 0xff);
284 
285  // Crawl attachment
286  if (Status==C4PF_Ray_Crawl)
287  {
288  int32_t iX=0,iY=0; CrawlToAttach(iX,iY,CrawlAttach);
289  pDraw->DrawLineDw(cgo.Surface,
290  cgo.X+X2-cgo.TargetX,cgo.Y+Y2-cgo.TargetY,
291  cgo.X+X2-cgo.TargetX+7*iX,cgo.Y+Y2-cgo.TargetY+7*iY,
292  C4RGB(0xff, 0, 0));
293  }
294 
295  // Ray line
296  pDraw->DrawLineDw(cgo.Surface,
297  cgo.X+X-cgo.TargetX,cgo.Y+Y-cgo.TargetY,
298  cgo.X+X2-cgo.TargetX,cgo.Y+Y2-cgo.TargetY,
299  Color);
300 
301  // Crawler point
303  cgo.X+X2-cgo.TargetX-1,cgo.Y+Y2-cgo.TargetY-1,
304  cgo.X+X2-cgo.TargetX+1,cgo.Y+Y2-cgo.TargetY+1,
305  (Status==C4PF_Ray_Crawl) ? ((Direction==C4PF_Direction_Left) ? C4RGB(0, 0xff, 0) : C4RGB(0, 0, 0xff)) : Color);
306 
307  // Search target point
309  cgo.X+TargetX-cgo.TargetX-2,cgo.Y+TargetY-cgo.TargetY-2,
310  cgo.X+TargetX-cgo.TargetX+2,cgo.Y+TargetY-cgo.TargetY+2,
311  C4RGB(0xff, 0xff, 0));
312 
313 }
314 
315 bool C4PathFinderRay::PathFree(int32_t &rX, int32_t &rY, int32_t iToX, int32_t iToY, C4TransferZone **ppZone)
316 {
317  int32_t d,dx,dy,aincr,bincr,xincr,yincr,x,y;
318  // Y based
319  if (Abs(iToX-rX)<Abs(iToY-rY))
320  {
321  xincr=(iToX>rX) ? +1 : -1; yincr=(iToY>rY) ? +1 : -1;
322  dy=Abs(iToY-rY); dx=Abs(iToX-rX);
323  d=2*dx-dy; aincr=2*(dx-dy); bincr=2*dx; x=rX; y=rY;
324  for (y=rY; y!=iToY; y+=yincr)
325  {
326  // Check point free
327  if (PointFree(x,y)) { rY=y; rX=x; }
328  else return false;
329  // Check transfer zone intersection
330  if (ppZone)
331  if (pPathFinder->TransferZonesEnabled)
332  if (pPathFinder->TransferZones)
333  if ((*ppZone = pPathFinder->TransferZones->Find(rX,rY)))
334  return false;
335  // Advance
336  if (d>=0) { x+=xincr; d+=aincr; }
337  else d+=bincr;
338  }
339  }
340  // X based
341  else
342  {
343  yincr=(iToY>rY) ? +1 : -1; xincr=(iToX>rX) ? +1 : -1;
344  dx=Abs(iToX-rX); dy=Abs(iToY-rY);
345  d=2*dy-dx; aincr=2*(dy-dx); bincr=2*dy; x=rX; y=rY;
346  for (x=rX; x!=iToX; x+=xincr)
347  {
348  // Check point free
349  if (PointFree(x,y)) { rY=y; rX=x; }
350  else return false;
351  // Check transfer zone intersection
352  if (ppZone)
353  if (pPathFinder->TransferZonesEnabled)
354  if (pPathFinder->TransferZones)
355  if ((*ppZone = pPathFinder->TransferZones->Find(rX,rY)))
356  return false;
357  // Advance
358  if (d>=0) { y+=yincr; d+=aincr; }
359  else d+=bincr;
360  }
361  }
362 
363  return true;
364 }
365 
367 {
368 
369  // No attach: crawl failure (shouldn't ever get here)
370  if (!CrawlAttach)
371  return false;
372 
373  // Last attach lost (don't check on first crawl for that might be a diagonal attach)
374  if (CrawlLength)
376  {
377  // Crawl corner by last attach
380  // Safety: new attach not found - unexpected failure
382  return false;
383  // Corner okay
384  return true;
385  }
386 
387  // Check crawl target by attach
388  int32_t iTurned=0;
390  {
391  // Crawl target not free: turn attach
392  TurnAttach(CrawlAttach,Direction); iTurned++;
393  // Turned four times: all enclosed, crawl failure
394  if (iTurned==4)
395  return false;
396  }
397 
398  // Crawl by attach
400 
401  // Success
402  return true;
403 
404 }
405 
407 {
408  C4PathFinderRay *pRay;
409  // Back shorten
410  for (pRay=this; pRay->From; pRay=pRay->From)
411  while (pRay->CheckBackRayShorten()) {}
412  // Set all waypoints
413  for (pRay=this; pRay->From; pRay=pRay->From)
414  {
415  // Transfer waypoint
416  if (pRay->UseZone)
417  pPathFinder->SetWaypoint(pRay->X2,pRay->Y2,pRay->UseZone->Object);
418  // MoveTo waypoint
419  else
420  pPathFinder->SetWaypoint(pRay->From->X2,pRay->From->Y2,nullptr);
421  }
422 }
423 
424 bool C4PathFinderRay::PointFree(int32_t iX, int32_t iY)
425 {
426  return pPathFinder->PointFree(iX,iY);
427 }
428 
429 bool C4PathFinderRay::CrawlTargetFree(int32_t iX, int32_t iY, int32_t iAttach, int32_t iDirection)
430 {
431  CrawlByAttach(iX,iY,iAttach,iDirection);
432  return PointFree(iX,iY);
433 }
434 
435 void C4PathFinderRay::CrawlByAttach(int32_t &rX, int32_t &rY, int32_t iAttach, int32_t iDirection)
436 {
437  switch (iAttach)
438  {
439  case C4PF_Crawl_Top: rX+=iDirection; break;
440  case C4PF_Crawl_Bottom: rX-=iDirection; break;
441  case C4PF_Crawl_Left: rY-=iDirection; break;
442  case C4PF_Crawl_Right: rY+=iDirection; break;
443  }
444 }
445 
446 void C4PathFinderRay::TurnAttach(int32_t &rAttach, int32_t iDirection)
447 {
448  rAttach+=iDirection;
449  if (rAttach>C4PF_Crawl_Left) rAttach=C4PF_Crawl_Top;
450  if (rAttach<C4PF_Crawl_Top) rAttach=C4PF_Crawl_Left;
451 }
452 
453 int32_t C4PathFinderRay::FindCrawlAttach(int32_t iX, int32_t iY)
454 {
455  if (!PointFree(iX,iY-1)) return C4PF_Crawl_Top;
456  if (!PointFree(iX,iY+1)) return C4PF_Crawl_Bottom;
457  if (!PointFree(iX-1,iY)) return C4PF_Crawl_Left;
458  if (!PointFree(iX+1,iY)) return C4PF_Crawl_Right;
459  return C4PF_Crawl_NoAttach;
460 }
461 
462 void C4PathFinderRay::CrawlToAttach(int32_t &rX, int32_t &rY, int32_t iAttach)
463 {
464  switch (iAttach)
465  {
466  case C4PF_Crawl_Top: rY--; break;
467  case C4PF_Crawl_Bottom: rY++; break;
468  case C4PF_Crawl_Left: rX--; break;
469  case C4PF_Crawl_Right: rX++; break;
470  }
471 }
472 
473 bool C4PathFinderRay::IsCrawlAttach(int32_t iX, int32_t iY, int32_t iAttach)
474 {
475  CrawlToAttach(iX,iY,iAttach);
476  return !PointFree(iX,iY);
477 }
478 
479 int32_t C4PathFinderRay::FindCrawlAttachDiagonal(int32_t iX, int32_t iY, int32_t iDirection)
480 {
481  // Going left
482  if (iDirection==C4PF_Direction_Left)
483  {
484  // Top Left
485  if (!PointFree(iX-1,iY-1)) return C4PF_Crawl_Top;
486  // Bottom left
487  if (!PointFree(iX-1,iY+1)) return C4PF_Crawl_Left;
488  // Top right
489  if (!PointFree(iX+1,iY-1)) return C4PF_Crawl_Right;
490  // Bottom right
491  if (!PointFree(iX+1,iY+1)) return C4PF_Crawl_Bottom;
492  }
493  // Going right
494  if (iDirection==C4PF_Direction_Right)
495  {
496  // Top Left
497  if (!PointFree(iX-1,iY-1)) return C4PF_Crawl_Left;
498  // Bottom left
499  if (!PointFree(iX-1,iY+1)) return C4PF_Crawl_Bottom;
500  // Top right
501  if (!PointFree(iX+1,iY-1)) return C4PF_Crawl_Top;
502  // Bottom right
503  if (!PointFree(iX+1,iY+1)) return C4PF_Crawl_Right;
504  }
505  return C4PF_Crawl_NoAttach;
506 }
507 
509 {
510  C4PathFinderRay *pRay,*pRay2;
511  int32_t iX,iY;
512  for (pRay=From; pRay; pRay=pRay->From)
513  {
514  // Don't shorten transfer over zones
515  if (pRay->UseZone) return false;
516  // Skip self
517  if (pRay==From) continue;
518  // Check shortcut
519  iX=X; iY=Y;
520  if (PathFree(iX,iY,pRay->X,pRay->Y))
521  {
522  // Delete jumped rays
523  for (pRay2=From; pRay2!=pRay; pRay2=pRay2->From)
524  pRay2->Status=C4PF_Ray_Deleted;
525  // Shorten pRay to this
526  pRay->X2=X; pRay->Y2=Y;
527  From=pRay;
528  // Success
529  return true;
530  }
531  }
532  return false;
533 }
534 
535 //------------------------------- C4PathFinder ---------------------------------------------
536 
538 {
539  Default();
540 }
541 
543 {
544  Clear();
545 }
546 
548 {
549  PointFree=nullptr;
550  SetWaypoint=nullptr;
551  FirstRay=nullptr;
552  Success=false;
553  TransferZones=nullptr;
554  TransferZonesEnabled=true;
555  Level=1;
556 }
557 
559 {
560  C4PathFinderRay *pRay,*pNext;
561  for (pRay=FirstRay; pRay; pRay=pNext) { pNext=pRay->Next; delete pRay; }
562  FirstRay=nullptr;
563 }
564 
565 void C4PathFinder::Init(PointFreeFn fnPointFree, C4TransferZones* pTransferZones)
566 {
567  // Set data
568  PointFree = fnPointFree;
569  TransferZones = pTransferZones;
570 }
571 
573 {
574  TransferZonesEnabled = fEnabled;
575 }
576 
577 void C4PathFinder::SetLevel(int iLevel)
578 {
579  Level = Clamp(iLevel, 1, 10);
580 }
581 
583 {
584  if (TransferZones) TransferZones->Draw(cgo);
585  for (C4PathFinderRay *pRay=FirstRay; pRay; pRay=pRay->Next) pRay->Draw(cgo);
586 }
587 
588 void C4PathFinder::Run()
589 {
590  if (TransferZones) TransferZones->ClearUsed();
591  Success=false;
592  while (!Success && Execute()) {}
593  // Notice that ray zone-pointers might be invalid after run
594 }
595 
596 bool C4PathFinder::Execute()
597 {
598 
599  // Execute & count rays
600  bool fContinue=false;
601  int32_t iRays=0;
602  for (C4PathFinderRay *pRay=FirstRay; pRay && !Success; pRay=pRay->Next,iRays++)
603  if (pRay->Execute())
604  fContinue=true;
605 
606  // Max ray limit
607  if (iRays>=C4PF_MaxRay) return false;
608 
609  // Draw
611  {
612  static int32_t iDelay=0;
613  iDelay++; if (iDelay>C4PF_Draw_Rate)
614  {
615  iDelay=0;
617  }
618  }
619 
620  return fContinue;
621 }
622 
623 bool C4PathFinder::Find(int32_t iFromX, int32_t iFromY, int32_t iToX, int32_t iToY, SetWaypointFn fnSetWaypoint)
624 {
625 
626  // Prepare
627  Clear();
628 
629  // Parameter safety
630  if (!fnSetWaypoint) return false;
631  SetWaypoint=fnSetWaypoint;
632 
633  // Start & target coordinates must be free
634  if (!PointFree(iFromX,iFromY) || !PointFree(iToX,iToY)) return false;
635 
636  // Add the first two rays
637  if (!AddRay(iFromX,iFromY,iToX,iToY,0,C4PF_Direction_Left,nullptr)) return false;
638  if (!AddRay(iFromX,iFromY,iToX,iToY,0,C4PF_Direction_Right,nullptr)) return false;
639 
640  // Run
641  Run();
642 
643  // Success
644  return Success;
645 
646 }
647 
648 bool C4PathFinder::AddRay(int32_t iFromX, int32_t iFromY, int32_t iToX, int32_t iToY, int32_t iDepth, int32_t iDirection, C4PathFinderRay *pFrom, C4TransferZone *pUseZone)
649 {
650  // Max depth
651  if (iDepth >= C4PF_MaxDepth * Level) return false;
652  // Allocate and set new ray
653  C4PathFinderRay *pRay;
654  if (!(pRay = new C4PathFinderRay)) return false;
655  pRay->X=iFromX; pRay->Y=iFromY;
656  pRay->X2=iFromX; pRay->Y2=iFromY;
657  pRay->TargetX=iToX; pRay->TargetY=iToY;
658  pRay->Depth=iDepth;
659  pRay->Direction=iDirection;
660  pRay->From=pFrom;
661  pRay->pPathFinder=this;
662  pRay->Next=FirstRay;
663  pRay->UseZone=pUseZone;
664  FirstRay=pRay;
665  return true;
666 }
667 
668 bool C4PathFinder::SplitRay(C4PathFinderRay *pRay, int32_t iAtX, int32_t iAtY)
669 {
670  // Max depth
671  if (pRay->Depth >= C4PF_MaxDepth * Level) return false;
672  // Allocate and set new ray
673  C4PathFinderRay *pNewRay;
674  if (!(pNewRay = new C4PathFinderRay)) return false;
675  pNewRay->Status=C4PF_Ray_Still;
676  pNewRay->X=pRay->X; pNewRay->Y=pRay->Y;
677  pNewRay->X2=iAtX; pNewRay->Y2=iAtY;
678  pNewRay->TargetX=pRay->TargetX; pNewRay->TargetY=pRay->TargetY;
679  pNewRay->Depth=pRay->Depth;
680  pNewRay->Direction=pRay->Direction;
681  pNewRay->From=pRay->From;
682  pNewRay->pPathFinder=this;
683  pNewRay->Next=FirstRay;
684  FirstRay=pNewRay;
685  // Adjust split ray
686  pRay->From=pNewRay;
687  pRay->X=iAtX; pRay->Y=iAtY;
688  return true;
689 }
690 
691 
C4Draw * pDraw
Definition: C4Draw.cpp:42
C4GraphicsSystem GraphicsSystem
Definition: C4Globals.cpp:51
const int32_t C4PF_Ray_Launch
const int32_t C4PF_MaxRay
const int32_t C4PF_Crawl_NoAttach
const int32_t C4PF_Ray_Crawl
const int32_t C4PF_Crawl_Bottom
const int32_t C4PF_Direction_Right
const int32_t C4PF_Ray_Failure
const int32_t C4PF_Draw_Rate
const int32_t C4PF_MaxCrawl
const int32_t C4PF_MaxDepth
const int32_t C4PF_Ray_Still
const int32_t C4PF_Ray_Deleted
const int32_t C4PF_Crawl_Left
const int32_t C4PF_Direction_Left
const int32_t C4PF_Threshold
const int32_t C4PF_Crawl_Right
const int32_t C4PF_Crawl_Top
int32_t Distance(int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2)
Definition: Standard.cpp:25
T Abs(T val)
Definition: Standard.h:42
T Clamp(T bval, T lbound, T rbound)
Definition: Standard.h:44
#define C4RGB(r, g, b)
Definition: StdColors.h:26
void DrawFrameDw(C4Surface *sfcDest, int x1, int y1, int x2, int y2, DWORD dwClr, float width=1.0f)
Definition: C4Draw.cpp:635
void DrawLineDw(C4Surface *sfcTarget, float x1, float y1, float x2, float y2, DWORD dwClr, float width=1.0f)
Definition: C4Draw.cpp:608
C4Surface * Surface
Definition: C4Facet.h:117
float Y
Definition: C4Facet.h:118
float X
Definition: C4Facet.h:118
std::function< bool(int32_t x, int32_t y)> PointFreeFn
Definition: C4PathFinder.h:34
void EnableTransferZones(bool fEnabled)
void Init(PointFreeFn fnPointFree, C4TransferZones *pTransferZones=nullptr)
void SetLevel(int iLevel)
void Draw(C4TargetFacet &cgo)
bool Find(int32_t iFromX, int32_t iFromY, int32_t iToX, int32_t iToY, SetWaypointFn fnSetWaypoint)
std::function< bool(int32_t x, int32_t y, C4Object *transfer_object)> SetWaypointFn
Definition: C4PathFinder.h:35
bool CrawlTargetFree(int32_t iX, int32_t iY, int32_t iAttach, int32_t iDirection)
void Draw(C4TargetFacet &cgo)
bool CheckBackRayShorten()
C4PathFinderRay * Next
int32_t FindCrawlAttach(int32_t iX, int32_t iY)
C4TransferZone * UseZone
bool PointFree(int32_t iX, int32_t iY)
void TurnAttach(int32_t &rAttach, int32_t iDirection)
C4PathFinder * pPathFinder
C4PathFinderRay * From
int32_t CrawlStartAttach
int32_t FindCrawlAttachDiagonal(int32_t iX, int32_t iY, int32_t iDirection)
bool PathFree(int32_t &rX, int32_t &rY, int32_t iToX, int32_t iToY, C4TransferZone **ppZone=nullptr)
bool IsCrawlAttach(int32_t iX, int32_t iY, int32_t iAttach)
void CrawlByAttach(int32_t &rX, int32_t &rY, int32_t iAttach, int32_t iDirection)
void CrawlToAttach(int32_t &rX, int32_t &rY, int32_t iAttach)
float TargetY
Definition: C4Facet.h:165
float TargetX
Definition: C4Facet.h:165
bool GetEntryPoint(int32_t &rX, int32_t &rY, int32_t iToX, int32_t iToY)
C4Object * Object
bool At(int32_t iX, int32_t iY)
void Draw(C4TargetFacet &cgo)
C4TransferZone * Find(C4Object *pObj)