OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4TransferZone.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 /* Special regions to extend the pathfinder */
19 
20 #include "C4Include.h"
22 
23 #include "graphics/C4FacetEx.h"
24 #include "graphics/C4Draw.h"
25 #include "landscape/C4Landscape.h"
26 #include "object/C4GameObjects.h"
27 #include "lib/StdColors.h"
28 
30 {
31  Object = nullptr;
32  X = Y = Wdt = Hgt = 0;
33  Next = nullptr;
34  Used = false;
35 }
36 
38 {
39 }
40 
42 {
43  Default();
44 }
45 
47 {
48  Clear();
49 }
50 
52 {
53  First=nullptr;
54 }
55 
57 {
58  C4TransferZone *pZone,*pNext;
59  for (pZone=First; pZone; pZone=pNext) { pNext=pZone->Next; delete pZone; }
60  First=nullptr;
61 }
62 
64 {
65  // Clear object pointers
66  for (C4TransferZone *pZone=First; pZone; pZone=pZone->Next)
67  if (pZone->Object==pObj)
68  pZone->Object=nullptr;
69  // Remove cleared zones immediately
71 }
72 
73 bool C4TransferZones::Set(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, C4Object *pObj)
74 {
75  C4TransferZone *pZone;
76  // Empty zone: clear existing object zones
77  if (!iWdt || !iHgt) { ClearPointers(pObj); return true; }
78  // Update existing zone
79  if ((pZone=Find(pObj)))
80  {
81  pZone->X=iX; pZone->Y=iY;
82  pZone->Wdt=iWdt; pZone->Hgt=iHgt;
83  }
84  // Allocate and add new zone
85  else
86  Add(iX,iY,iWdt,iHgt,pObj);
87  // Success
88  return true;
89 }
90 
91 bool C4TransferZones::Add(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, C4Object *pObj)
92 {
93  C4TransferZone *pZone;
94  // Allocate and add new zone
95  pZone = new C4TransferZone;
96  pZone->X=iX; pZone->Y=iY;
97  pZone->Wdt=iWdt; pZone->Hgt=iHgt;
98  pZone->Object=pObj;
99  pZone->Next=First;
100  First=pZone;
101  // Success
102  return true;
103 }
104 
106 {
107  Clear();
109 }
110 
111 C4TransferZone* C4TransferZones::Find(int32_t iX, int32_t iY)
112 {
113  for (C4TransferZone *pZone=First; pZone; pZone=pZone->Next)
114  if (Inside<int32_t>(iX-pZone->X,0,pZone->Wdt-1))
115  if (Inside<int32_t>(iY-pZone->Y,0,pZone->Hgt-1))
116  return pZone;
117  return nullptr;
118 }
119 
121 {
122  for (C4TransferZone *pZone=First; pZone; pZone=pZone->Next)
123  pZone->Draw(cgo);
124 }
125 
126 void C4TransferZone::Draw(C4TargetFacet &cgo, bool fHighlight)
127 {
128  if (Used) fHighlight=true;
130  int(cgo.X+X-cgo.TargetX),int(cgo.Y+Y-cgo.TargetY),
131  int(cgo.X+X-cgo.TargetX+Wdt-1),int(cgo.Y+Y-cgo.TargetY+Hgt-1),
132  fHighlight ? C4RGB(0, 0xca, 0) : C4RGB(0xca, 0, 0));
133 }
134 
135 bool C4TransferZone::At(int32_t iX, int32_t iY)
136 {
137  return (Inside<int32_t>(iX-X,0,Wdt-1) && Inside<int32_t>(iY-Y,0,Hgt-1));
138 }
139 
141 {
142  int32_t iResult=0;
143  C4TransferZone *pZone,*pNext,*pPrev=nullptr;
144  for (pZone=First; pZone; pZone=pNext)
145  {
146  pNext=pZone->Next;
147  if (!pZone->Object)
148  {
149  delete pZone;
150  if (pPrev) pPrev->Next=pNext;
151  else First=pNext;
152  iResult++;
153  }
154  else
155  pPrev=pZone;
156  }
157  return iResult;
158 }
159 
160 void AdjustMoveToTarget(int32_t &rX, int32_t &rY, bool fFreeMove, int32_t iShapeHgt);
161 
162 bool C4TransferZone::GetEntryPoint(int32_t &rX, int32_t &rY, int32_t iToX, int32_t iToY)
163 {
164  // Target inside zone: move outside horizontally
165  if (Inside<int32_t>(iToX-X,0,Wdt-1) && Inside<int32_t>(iToY-Y,0,Hgt-1))
166  {
167  if (iToX<X+Wdt/2) iToX=X-1;
168  else iToX=X+Wdt;
169  }
170  // Get closest adjacent point
171  rX=Clamp<int32_t>(iToX,X-1,X+Wdt);
172  rY=Clamp<int32_t>(iToY,Y-1,Y+Hgt);
173  // Search around zone for free
174  int32_t iX1=rX,iY1=rY,iX2=rX,iY2=rY;
175  int32_t iXIncr1=0,iYIncr1=-1,iXIncr2=0,iYIncr2=+1;
176  int32_t cnt;
177  for (cnt=0; cnt<2*Wdt+2*Hgt; cnt++)
178  {
179  // Found free
180  if (!GBackSolid(iX1,iY1)) { rX=iX1; rY=iY1; break; }
181  if (!GBackSolid(iX2,iY2)) { rX=iX2; rY=iY2; break; }
182  // Advance
183  iX1+=iXIncr1; iY1+=iYIncr1;
184  iX2+=iXIncr2; iY2+=iYIncr2;
185  // Corners
186  if (iY1<Y-1) { iY1=Y-1; iXIncr1=+1; iYIncr1=0; }
187  if (iX1>X+Wdt) { iX1=X+Wdt; iXIncr1=0; iYIncr1=+1; }
188  if (iY1>Y+Hgt) { iY1=Y+Hgt; iXIncr1=-1; iYIncr1=0; }
189  if (iX1<X-1) { iX1=X-1; iXIncr1=0; iYIncr1=-1; }
190  if (iY2<Y-1) { iY2=Y-1; iXIncr2=-1; iYIncr2=0; }
191  if (iX2>X+Wdt) { iX2=X+Wdt; iXIncr2=0; iYIncr2=-1; }
192  if (iY2>Y+Hgt) { iY2=Y+Hgt; iXIncr2=+1; iYIncr2=0; }
193  if (iX2<X-1) { iX2=X-1; iXIncr2=0; iYIncr2=+1; }
194  }
195  // No free found
196  if (cnt>=2*Wdt+2*Hgt) return false;
197  // Vertical walk-to adjust (only if at the side of zone)
198  if (!Inside<int32_t>(rX-X,0,Wdt-1))
199  AdjustMoveToTarget(rX,rY,false,20);
200  // Success
201  return true;
202 }
203 
205 {
206  for (C4TransferZone *pZone=First; pZone; pZone=pZone->Next)
207  pZone->Used=false;
208 }
209 
211 {
212  for (C4TransferZone *pZone=First; pZone; pZone=pZone->Next)
213  if (pZone->Object==pObj)
214  return pZone;
215  return nullptr;
216 }
void ClearPointers(C4Object *pObj)
void Draw(C4TargetFacet &cgo)
float Y
Definition: C4Facet.h:120
C4TransferZone * Next
void Draw(C4TargetFacet &cgo, bool fHighlight=false)
bool Add(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, C4Object *pObj)
int32_t RemoveNullZones()
C4TransferZone * Find(C4Object *pObj)
void DrawFrameDw(C4Surface *sfcDest, int x1, int y1, int x2, int y2, DWORD dwClr, float width=1.0f)
Definition: C4Draw.cpp:644
bool Set(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, C4Object *pObj)
int iResult
Definition: C4GroupMain.cpp:39
C4TransferZone * First
C4Object * Object
bool GetEntryPoint(int32_t &rX, int32_t &rY, int32_t iToX, int32_t iToY)
C4Draw * pDraw
Definition: C4Draw.cpp:45
#define C4RGB(r, g, b)
Definition: StdColors.h:28
bool At(int32_t iX, int32_t iY)
float TargetX
Definition: C4Facet.h:167
C4Surface * Surface
Definition: C4Facet.h:119
float TargetY
Definition: C4Facet.h:167
void AdjustMoveToTarget(int32_t &rX, int32_t &rY, bool fFreeMove, int32_t iShapeHgt)
Definition: C4Command.cpp:144
float X
Definition: C4Facet.h:120
C4GameObjects Objects
Definition: C4Globals.cpp:48
bool GBackSolid(int32_t x, int32_t y)
Definition: C4Landscape.h:232