OpenClonk
C4SolidMask Class Reference

#include <C4SolidMask.h>

Collaboration diagram for C4SolidMask:
[legend]

Classes

class  DensityProvider
 

Public Member Functions

void Put (bool fCauseInstability, C4TargetRect *pClipRect, bool fRestoreAttachment)
 
void Remove (bool fBackupAttachment)
 
void Draw (C4TargetFacet &cgo)
 
bool IsPut ()
 
 C4SolidMask (C4Object *pForObject)
 
 ~C4SolidMask ()
 
void SetHalfVehicle (bool set)
 

Static Public Member Functions

static bool CheckConsistency ()
 
static void RemoveSolidMasks ()
 
static void PutSolidMasks ()
 
static CSurface8LoadMaskFromFile (class C4Group &hGroup, const char *szFilename)
 

Public Attributes

C4SolidMaskPrev
 
C4SolidMaskNext
 

Static Public Attributes

static C4SolidMaskFirst = nullptr
 
static C4SolidMaskLast = nullptr
 

Protected Member Functions

void RemoveTemporary (C4Rect where)
 
void PutTemporary (C4Rect where)
 
void Repair (C4Rect where)
 

Protected Attributes

bool MaskPut
 
int MaskPutRotation
 
int MatBuffPitch
 
C4Real MaskRemovalX
 
int32_t MaskRemovalY
 
class C4Object ** ppAttachingObjects
 
int iAttachingObjectsCount
 
int iAttachingObjectsCapacity
 
C4TargetRect MaskPutRect
 
BYTEpSolidMaskMatBuff
 
BYTE MaskMaterial
 
C4ObjectpForObject
 

Friends

class C4Landscape
 
class DensityProvider
 

Detailed Description

Definition at line 25 of file C4SolidMask.h.

Constructor & Destructor Documentation

◆ C4SolidMask()

C4SolidMask::C4SolidMask ( C4Object pForObject)

Definition at line 408 of file C4SolidMask.cpp.

409 {
410  // zero fields
411  MaskPut=false;
412  MaskPutRotation=0;
413  MaskRemovalX = Fix0;
414  MaskRemovalY = 0;
415  ppAttachingObjects=nullptr;
418  // Update linked list
419  Next = nullptr;
420  Prev = Last;
421  Last = this;
422  if (Prev) Prev->Next = this;
423  else First = this;
424  // create mat buff to store the material replaced by the solid mask
425  // the upper left corner is here the [objpos]+rot([shapexy]+[targetxy]+[realWH]/2)-maxWH/2
427  if (!(pSolidMaskMatBuff= new BYTE [MatBuffPitch * MatBuffPitch] )) return;
429 }
BYTE MCVehic
Definition: C4Material.cpp:37
const C4Real Fix0
Definition: C4Real.h:312
uint8_t BYTE
C4TargetRect SolidMask
Definition: C4Object.h:148
int32_t Hgt
Definition: C4Rect.h:30
int32_t Wdt
Definition: C4Rect.h:30
int MaskPutRotation
Definition: C4SolidMask.h:29
static C4SolidMask * Last
Definition: C4SolidMask.h:72
class C4Object ** ppAttachingObjects
Definition: C4SolidMask.h:37
bool MaskPut
Definition: C4SolidMask.h:28
C4Real MaskRemovalX
Definition: C4SolidMask.h:34
int iAttachingObjectsCapacity
Definition: C4SolidMask.h:38
BYTE * pSolidMaskMatBuff
Definition: C4SolidMask.h:42
C4SolidMask * Prev
Definition: C4SolidMask.h:73
int MatBuffPitch
Definition: C4SolidMask.h:30
static C4SolidMask * First
Definition: C4SolidMask.h:71
C4Object * pForObject
Definition: C4SolidMask.h:46
int iAttachingObjectsCount
Definition: C4SolidMask.h:38
int32_t MaskRemovalY
Definition: C4SolidMask.h:35
BYTE MaskMaterial
Definition: C4SolidMask.h:44
C4SolidMask * Next
Definition: C4SolidMask.h:74

References First, Fix0, C4Rect::Hgt, iAttachingObjectsCapacity, iAttachingObjectsCount, Last, MaskMaterial, MaskPut, MaskPutRotation, MaskRemovalX, MaskRemovalY, MatBuffPitch, MCVehic, Next, pForObject, ppAttachingObjects, Prev, pSolidMaskMatBuff, C4Object::SolidMask, and C4Rect::Wdt.

◆ ~C4SolidMask()

C4SolidMask::~C4SolidMask ( )

Definition at line 431 of file C4SolidMask.cpp.

432 {
433  Remove(false);
434  // Update linked list
435  if (Next) Next->Prev = Prev;
436  if (Prev) Prev->Next = Next;
437  if (First == this) First = Next;
438  if (Last == this) Last = Prev;
439  delete [] pSolidMaskMatBuff;
440  delete [] ppAttachingObjects;
441 }
void Remove(bool fBackupAttachment)

References First, Last, Next, ppAttachingObjects, Prev, pSolidMaskMatBuff, and Remove().

Here is the call graph for this function:

Member Function Documentation

◆ CheckConsistency()

bool C4SolidMask::CheckConsistency ( )
static

Definition at line 468 of file C4SolidMask.cpp.

469 {
470  if (!SOLIDMASK_DEBUG)
471  return true;
472 
473  C4Rect SolidMaskRect(0,0,::Landscape.GetWidth(),::Landscape.GetHeight());
474  C4SolidMask *pSolid;
475  for (pSolid = C4SolidMask::Last; pSolid; pSolid = pSolid->Prev)
476  {
477  pSolid->RemoveTemporary(SolidMaskRect);
478  }
479  assert(!::Landscape.GetMatCount(MVehic));
480  // Restore Solidmasks
481  for (pSolid = C4SolidMask::First; pSolid; pSolid = pSolid->Next)
482  {
483  pSolid->PutTemporary(SolidMaskRect);
484  }
485  return true;
486 }
constexpr bool SOLIDMASK_DEBUG
Definition: C4Include.h:39
C4Landscape Landscape
int32_t MVehic
Definition: C4Material.cpp:36
int32_t GetWidth() const
int32_t GetHeight() const
int32_t GetMatCount(int material) const
Definition: C4Rect.h:28
void PutTemporary(C4Rect where)
void RemoveTemporary(C4Rect where)

References First, C4Landscape::GetHeight(), C4Landscape::GetMatCount(), C4Landscape::GetWidth(), Landscape, Last, MVehic, Next, Prev, PutTemporary(), RemoveTemporary(), and SOLIDMASK_DEBUG.

Referenced by C4Landscape::DoRelights(), C4Landscape::P::FinishChange(), Put(), and Remove().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Draw()

void C4SolidMask::Draw ( C4TargetFacet cgo)

Definition at line 330 of file C4SolidMask.cpp.

331 {
332  // only if put
333  if (!MaskPut) return;
334  // set topface facet
336  // draw it
337  if (MaskPutRotation)
339  else
341 }
C4Surface * GetBitmap(DWORD dwClr=0)
void Set(C4Surface &rSfc)
Definition: C4Facet.cpp:459
C4Surface * Surface
Definition: C4Facet.h:117
float Hgt
Definition: C4Facet.h:118
float Wdt
Definition: C4Facet.h:118
void DrawX(C4Surface *sfcTarget, float iX, float iY, float iWdt, float iHgt, int32_t iPhaseX=0, int32_t iPhaseY=0) const
Definition: C4Facet.cpp:358
float Y
Definition: C4Facet.h:118
void DrawXR(C4Surface *sfcTarget, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iPhaseX=0, int32_t iPhaseY=0, int32_t r=0)
Definition: C4Facet.cpp:238
float X
Definition: C4Facet.h:118
int32_t GetX() const
Definition: C4Object.h:285
int32_t GetY() const
Definition: C4Object.h:286
C4Shape Shape
Definition: C4Object.h:146
C4DefGraphics * GetGraphics() const
Definition: C4Object.h:339
int32_t y
Definition: C4Rect.h:30
int32_t x
Definition: C4Rect.h:30
float TargetY
Definition: C4Facet.h:165
float TargetX
Definition: C4Facet.h:165
int32_t tx
Definition: C4Rect.h:79
int32_t ty
Definition: C4Rect.h:79

References C4Facet::DrawX(), C4Facet::DrawXR(), C4DefGraphics::GetBitmap(), C4Object::GetGraphics(), C4Object::GetX(), C4Object::GetY(), C4Facet::Hgt, C4Rect::Hgt, MaskPut, MaskPutRotation, pForObject, C4Facet::Set(), C4Object::Shape, C4Object::SolidMask, C4Facet::Surface, C4TargetFacet::TargetX, C4TargetFacet::TargetY, C4TargetRect::tx, C4TargetRect::ty, C4Facet::Wdt, C4Rect::Wdt, C4Facet::X, C4Rect::x, C4Facet::Y, and C4Rect::y.

Referenced by C4Object::DrawSolidMask().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ IsPut()

bool C4SolidMask::IsPut ( )
inline

Definition at line 80 of file C4SolidMask.h.

80 { return MaskPut; }

References MaskPut.

◆ LoadMaskFromFile()

CSurface8 * C4SolidMask::LoadMaskFromFile ( class C4Group hGroup,
const char *  szFilename 
)
static

Definition at line 488 of file C4SolidMask.cpp.

489 {
490  // Construct SolidMask surface from PNG bitmap:
491  // All pixels that are more than 50% transparent are not solid
492  CPNGFile png;
493  StdBuf png_buf;
494  if (!hGroup.LoadEntry(szFilename, &png_buf)) return nullptr; // error messages done by caller
495  if (!png.Load((BYTE*)png_buf.getMData(), png_buf.getSize())) return nullptr;
496  CSurface8 *result = new CSurface8(png.iWdt, png.iHgt);
497  for (size_t y=0u; y<png.iHgt; ++y)
498  for (size_t x=0u; x<png.iWdt; ++x)
499  result->SetPix(x,y,((png.GetPix(x,y)>>24)<128) ? 0x00 : 0xff);
500  return result;
501 }
unsigned long iHgt
Definition: StdPNG.h:44
bool Load(BYTE *pFile, int iSize)
Definition: StdPNG.cpp:155
unsigned long iWdt
Definition: StdPNG.h:44
DWORD GetPix(int iX, int iY)
Definition: StdPNG.cpp:175
void SetPix(int iX, int iY, BYTE byCol)
Definition: CSurface8.h:37
Definition: StdBuf.h:30
size_t getSize() const
Definition: StdBuf.h:101
void * getMData()
Definition: StdBuf.h:100

References StdBuf::getMData(), CPNGFile::GetPix(), StdBuf::getSize(), CPNGFile::iHgt, CPNGFile::iWdt, CPNGFile::Load(), C4Group::LoadEntry(), and CSurface8::SetPix().

Here is the call graph for this function:

◆ Put()

void C4SolidMask::Put ( bool  fCauseInstability,
C4TargetRect pClipRect,
bool  fRestoreAttachment 
)

Definition at line 32 of file C4SolidMask.cpp.

33 {
34  // If not put, put mask to background,
35  // storing background pixels in cSolidMask.
36 
37  // No mask
39  // Contained
40  if (pForObject->Contained) { iAttachingObjectsCount = 0; return; }
41  // Mask is put
42  if (fCauseInstability) CheckConsistency();
43 
44  bool RegularPut;
45  if (!pClipRect)
46  {
47  // Regular Put: Update MaskPutRect and MaskPutRotation
49  pClipRect = &MaskPutRect;
50  RegularPut = true;
51  }
52  else
53  {
54  // Reput by C4SolidMask::Remove
55  // Don't change MaskPutRotation or MaskPutRect
56  // Intersect ClipRect with the MaskPutRect
57  if (!pClipRect->ClipBy(MaskPutRect)) return;
58  RegularPut = false;
59  }
60  // Get mask surface
61  CSurface8 *pSolidMask = pForObject->Def->pSolidMask;
62  // Put mask pixels
63  int xcnt,ycnt,iTx,iTy;
64  BYTE byPixel;
65  // not rotated?
66  if (!MaskPutRotation)
67  {
68  // calc put rect
69  if (RegularPut)
70  {
71  int ox, oy;
74  MaskPutRect.x = ox;
75  if (MaskPutRect.x < 0) { MaskPutRect.tx = -MaskPutRect.x; MaskPutRect.x = 0; }
76  else MaskPutRect.tx = 0;
77  MaskPutRect.y = oy;
78  if (MaskPutRect.y < 0) { MaskPutRect.ty = -MaskPutRect.y; MaskPutRect.y = 0; }
79  else MaskPutRect.ty = 0;
80  MaskPutRect.Wdt = std::min<int32_t>(ox + pForObject->SolidMask.Wdt, ::Landscape.GetWidth()) - MaskPutRect.x;
81  MaskPutRect.Hgt = std::min<int32_t>(oy + pForObject->SolidMask.Hgt, ::Landscape.GetHeight()) - MaskPutRect.y;
82  }
83  // fill rect with mask
84  for (ycnt=0; ycnt<pClipRect->Hgt; ++ycnt)
85  {
86  BYTE *pPix=pSolidMask->Bits + (ycnt+pClipRect->ty+pForObject->SolidMask.y)*pSolidMask->Pitch + pClipRect->tx + pForObject->SolidMask.x;
87  for (xcnt=0; xcnt<pClipRect->Wdt; ++xcnt,++pPix)
88  {
89  if (*pPix)
90  {
91  // solid mask present here
92  // calc position in landscape
93  iTx=pClipRect->x+xcnt; iTy=pClipRect->y+ycnt;
94  // is background mat to be stored? always do this in the given rect
95  if (!MaskPut)
96  {
97  // get background pixel
98  byPixel=::Landscape.GetPix(iTx,iTy);
99  // store it. If MCVehic, also store in initial put, but won't be used in restore
100  // do not overwrite current value in re-put issued by SolidMask-remover
101  if (!IsSomeVehicle(byPixel) || RegularPut)
102  pSolidMaskMatBuff[(ycnt+pClipRect->ty)*MatBuffPitch+xcnt+pClipRect->tx]=byPixel;
103  }
104  // and set mask
106  }
107  else
108  // no SolidMask: mark buffer as unused here
109  if (!MaskPut)
110  pSolidMaskMatBuff[(ycnt+pClipRect->ty)*MatBuffPitch+xcnt+pClipRect->tx]=MCVehic;
111  }
112  }
113  }
114  else
115  {
116  // calc matrix for given rotation
118  Mb1 = Sin(itofix(-MaskPutRotation)), Mb2 = Cos(itofix(-MaskPutRotation));
119  // get upper-left corner of landscape copy rect
120  int centerx = pForObject->Def->Shape.x + pForObject->SolidMask.tx + pForObject->SolidMask.Wdt / 2;
121  int centery = pForObject->Def->Shape.y + pForObject->SolidMask.ty + pForObject->SolidMask.Hgt / 2;
122  int xstart = pForObject->GetX() + fixtoi(Ma1 * itofix(centerx) - Ma2 * itofix(centery)) - MatBuffPitch / 2;
123  int ystart = pForObject->GetY() + fixtoi(-Mb1 * itofix(centerx) + Mb2 * itofix(centery)) - MatBuffPitch / 2;
124  // store put rect
125  if (RegularPut)
126  {
127  MaskPutRect.x = xstart;
129  else { MaskPutRect.tx = 0; MaskPutRect.Wdt = 0; }
130  MaskPutRect.y = ystart;
132  else { MaskPutRect.ty = 0; MaskPutRect.Hgt = 0; }
133  MaskPutRect.Wdt = std::min<int32_t>(xstart + MatBuffPitch, ::Landscape.GetWidth()) - MaskPutRect.x;
134  MaskPutRect.Hgt = std::min<int32_t>(ystart + MatBuffPitch, ::Landscape.GetHeight()) - MaskPutRect.y;
135  }
136  // go through clipping rect
137  const C4Real y0 = itofix(pClipRect->ty - MatBuffPitch/2);
138  const C4Real x0 = itofix(pClipRect->tx - MatBuffPitch/2);
139  iTy=pClipRect->y;
140  int32_t w = pForObject->SolidMask.Wdt;
141  int32_t h = pForObject->SolidMask.Hgt;
142  int32_t mx0 = pForObject->SolidMask.x;
143  int32_t my0 = pForObject->SolidMask.y;
144  C4Real ya = y0 * Ma2;
145  C4Real yb = y0 * Mb2;
146  for (ycnt = 0; ycnt < pClipRect->Hgt; ycnt++)
147  {
148  iTx=pClipRect->x;
149  int i = (ycnt + pClipRect->ty) * MatBuffPitch + pClipRect->tx;
150  C4Real xa = x0 * Ma1;
151  C4Real xb = x0 * Mb1;
152  for (xcnt = 0; xcnt < pClipRect->Wdt; xcnt++)
153  {
154  // calc position in solidmask buffer
155  int32_t iMx = fixtoi(xa + ya) + w / 2;
156  int32_t iMy = fixtoi(xb + yb) + h / 2;
157  // in bounds? and solidmask?
158  if (iMx >= 0 && iMy >= 0 && iMx < w && iMy < h && pSolidMask->_GetPix(iMx+mx0, iMy+my0))
159  {
160  // is background mat to be stored?
161  if (!MaskPut)
162  {
163  // get background pixel
164  byPixel=::Landscape._GetPix(iTx,iTy);
165  // store it. If MCVehic, also store in initial put, but won't be used in restore
166  // do not overwrite current value in re-put issued by SolidMask-remover
167  if (!IsSomeVehicle(byPixel) || RegularPut)
168  pSolidMaskMatBuff[i + xcnt] = byPixel;
169  }
170  // set mask pix
172  }
173  else if (!MaskPut)
174  // mark pix as unused in buf
175  pSolidMaskMatBuff[i+xcnt] = MCVehic;
176  xa += Ma1; xb += Mb1;
177  ++iTx;
178  }
179  ya += Ma2; yb += Mb2;
180  ++iTy;
181  }
182  }
183  // Store mask put status
184  MaskPut=true;
185  // restore attached object positions if moved
186  if (fRestoreAttachment && iAttachingObjectsCount)
187  {
189  int32_t dy = pForObject->GetY() - MaskRemovalY;
190  if (dx != Fix0 || dy != 0)
191  for (int i = 0; i < iAttachingObjectsCount; ++i)
192  {
193  C4Object *pObj = ppAttachingObjects[i];
195  if (!pObj->Shape.ContactCheck(fixtoi(pObj->GetFixedX()+dx), fixtoi(pObj->GetFixedY()+dy)))
197  {
199  pObj->MovePosition(dx, itofix(dy));
200  }
201  }
203  }
204 
205  if (fCauseInstability) CheckConsistency();
206 }
C4Game Game
Definition: C4Globals.cpp:52
bool IsSomeVehicle(BYTE mat)
Definition: C4Material.h:226
C4Fixed itofix(int32_t x)
Definition: C4Real.h:261
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
C4Shape Shape
Definition: C4Def.h:104
CSurface8 * pSolidMask
Definition: C4Def.h:192
Definition: C4Real.h:59
int32_t FrameCounter
Definition: C4Game.h:129
BYTE GetPix(int32_t x, int32_t y) const
BYTE _GetPix(int32_t x, int32_t y) const
static const uint8_t Transparent
Definition: C4Landscape.h:50
bool SetPix2(int32_t x, int32_t y, BYTE fgPix, BYTE bgPix)
C4Real GetFixedX() const
Definition: C4Object.h:288
bool IsMoveableBySolidMask(int ComparisonPlane) const
int32_t GetSolidMaskPlane() const
int32_t iLastAttachMovementFrame
Definition: C4Object.h:125
void MovePosition(int32_t dx, int32_t dy)
Definition: C4Movement.cpp:675
int32_t GetR() const
Definition: C4Object.h:287
C4ObjectPtr Contained
Definition: C4Object.h:142
C4Def * Def
Definition: C4Object.h:141
C4Real GetFixedY() const
Definition: C4Object.h:289
bool ContactCheck(int32_t cx, int32_t cy, uint32_t *border_hack_contacts=nullptr, bool collide_halfvehic=false)
Definition: C4Shape.cpp:432
C4TargetRect MaskPutRect
Definition: C4SolidMask.h:40
static bool CheckConsistency()
bool ClipBy(C4TargetRect &rClip)
Definition: C4Rect.cpp:51
int Pitch
Definition: CSurface8.h:28
BYTE * Bits
Definition: CSurface8.h:30

References C4Landscape::_GetPix(), CSurface8::Bits, CheckConsistency(), C4TargetRect::ClipBy(), C4Shape::ContactCheck(), C4Object::Contained, Cos(), C4Object::Def, Fix0, fixtoi(), C4Game::FrameCounter, Game, C4Object::GetFixedX(), C4Object::GetFixedY(), C4Landscape::GetHeight(), C4Landscape::GetPix(), C4Object::GetR(), C4Object::GetSolidMaskPlane(), C4Landscape::GetWidth(), C4Object::GetX(), C4Object::GetY(), C4Rect::Hgt, iAttachingObjectsCount, C4Object::iLastAttachMovementFrame, C4Object::IsMoveableBySolidMask(), IsSomeVehicle(), itofix(), Landscape, MaskMaterial, MaskPut, MaskPutRect, MaskPutRotation, MaskRemovalX, MaskRemovalY, MatBuffPitch, MCVehic, C4Object::MovePosition(), pForObject, CSurface8::Pitch, ppAttachingObjects, C4Def::pSolidMask, pSolidMaskMatBuff, C4Landscape::SetPix2(), C4Def::Shape, C4Object::Shape, Sin(), C4Object::SolidMask, C4Landscape::Transparent, C4TargetRect::tx, C4TargetRect::ty, C4Rect::Wdt, C4Rect::x, and C4Rect::y.

Referenced by C4Object::UpdateSolidMask().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PutSolidMasks()

void C4SolidMask::PutSolidMasks ( )
static

Definition at line 453 of file C4SolidMask.cpp.

454 {
455  C4Rect SolidMaskRect(0,0,::Landscape.GetWidth(),::Landscape.GetHeight());
456  C4SolidMask *pSolid;
457  // Restore Solidmasks
458  for (pSolid = C4SolidMask::First; pSolid; pSolid = pSolid->Next)
459  {
460  pSolid->PutTemporary(SolidMaskRect);
461  }
462 }

References First, C4Landscape::GetHeight(), C4Landscape::GetWidth(), Landscape, Next, and PutTemporary().

Referenced by C4Game::ReloadDef(), C4Landscape::Save(), and C4Landscape::SaveDiff().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ PutTemporary()

void C4SolidMask::PutTemporary ( C4Rect  where)
protected

Definition at line 365 of file C4SolidMask.cpp.

366 {
367  if (!MaskPut || !pSolidMaskMatBuff) return;
368  where.Intersect(MaskPutRect);
369  // reput vehicle pixels
370  for (int y = where.y; y < where.y + where.Hgt; ++y)
371  {
372  for (int x = where.x; x < where.x + where.Wdt; ++x)
373  {
375  // only if mask was used here
376  if (!IsSomeVehicle(*pPix))
377  {
378  // put
379  assert(::Landscape.GetPix(x,y)==*pPix);
381  }
382  }
383  }
384 }
void _SetPix2Tmp(int32_t x, int32_t y, BYTE fgPix, BYTE bgPix)
void Intersect(const C4Rect &r2)
Definition: C4Rect.cpp:100

References C4Landscape::_SetPix2Tmp(), C4Landscape::GetPix(), C4Rect::Hgt, C4Rect::Intersect(), IsSomeVehicle(), Landscape, MaskMaterial, MaskPut, MaskPutRect, MatBuffPitch, pSolidMaskMatBuff, C4Landscape::Transparent, C4TargetRect::tx, C4TargetRect::ty, C4Rect::Wdt, C4Rect::x, and C4Rect::y.

Referenced by CheckConsistency(), C4Landscape::DoRelights(), and PutSolidMasks().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Remove()

void C4SolidMask::Remove ( bool  fBackupAttachment)

Definition at line 241 of file C4SolidMask.cpp.

242 {
243  // If put, restore background pixels from buffer
244 
245  // Not put
246  if (!MaskPut || !pSolidMaskMatBuff) return;
247 
249 
250  // reput background pixels
251  for (int ycnt=0; ycnt<MaskPutRect.Hgt; ++ycnt)
252  {
254  for (int xcnt=0; xcnt<MaskPutRect.Wdt; ++xcnt,++pPix)
255  // only if mask was used here
256  if (*pPix != MCVehic)
257  {
258  // calc position in landscape
259  int iTx=MaskPutRect.x+xcnt; int iTy=MaskPutRect.y+ycnt;
260  // restore pixel here
261  // The pPix-check ensures that only pixels that hads been overwritten by this SolidMask are restored
262  // Non-SolidMask-pixels should not happen here, because all relevant landscape change routines should
263  // temp remove SolidMasks before
264  assert(IsSomeVehicle(::Landscape._GetPix(iTx,iTy)));
265  if (IsSomeVehicle(::Landscape._GetPix(iTx, iTy)))
266  ::Landscape._SetPix2(iTx, iTy, *pPix, ::Landscape.Transparent);
267  // Instability
269  }
270  }
271  // Mask not put flag
272  MaskPut=false;
273  // update surrounding masks in that range
274  C4TargetRect ClipRect;
275  for (C4SolidMask *pSolid = C4SolidMask::Last; pSolid; pSolid = pSolid->Prev)
276  if (pSolid->MaskPut) if (pSolid->MaskPutRect.Overlap(MaskPutRect))
277  {
278  // set clipping rect for all calls, since they may modify it
280  // doubled solidmask-pixels have just been removed in the clipped area!
281  pSolid->MaskPut = false;
282  // re-put the solidmask
283  pSolid->Put(false, &ClipRect, false);
284  }
285 
286  // backup attachment if desired: Backup old pos and all objects that attach to or lie on the SolidMask
287  if (fBackupAttachment)
288  {
292  // Search in area slightly larger than SolidMask because objects might have vertices slightly outside their shape
294  C4LSector *pSct;
295  for (C4ObjectList *pLst=SolidArea.FirstObjectShapes(&pSct); pLst; pLst=SolidArea.NextObjectShapes(pLst, &pSct))
296  for (C4Object *pObj : *pLst)
297  if (pObj && pObj != pForObject && pObj->IsMoveableBySolidMask(pForObject->GetSolidMaskPlane()) && !pObj->Shape.CheckContact(pObj->GetX(),pObj->GetY()))
298  {
299  // avoid duplicate that may be found due to sector overlaps
300  bool has_dup = false;
301  for (int32_t i_dup = 0; i_dup < iAttachingObjectsCount; ++i_dup)
302  if (ppAttachingObjects[i_dup] == pObj)
303  {
304  has_dup = true;
305  break;
306  }
307  if (has_dup) continue;
308  // check for any contact to own SolidMask - attach-directions, bottom - "stuck" (CNAT_Center) is ignored, because that causes problems with things being stuck in basements :(
309  int iVtx = 0;
310  for (; iVtx < pObj->Shape.VtxNum; ++iVtx)
311  if (pObj->Shape.GetVertexContact(iVtx, pObj->Action.t_attach | CNAT_Bottom, pObj->GetX(), pObj->GetY(), DensityProvider(*this)))
312  break;
313  if (iVtx == pObj->Shape.VtxNum) continue; // no contact
314  // contact: Add object to list
316  {
318  C4Object **ppNewAttachingObjects = new C4Object *[iAttachingObjectsCapacity];
319  if (iAttachingObjectsCount) memcpy(ppNewAttachingObjects, ppAttachingObjects, sizeof(C4Object *) * iAttachingObjectsCount);
320  delete [] ppAttachingObjects;
321  ppAttachingObjects = ppNewAttachingObjects;
322  }
324  }
325  }
326 
328 }
const BYTE CNAT_Bottom
Definition: C4Constants.h:112
C4GameObjects Objects
Definition: C4Globals.cpp:48
C4LSectors Sectors
Definition: C4GameObjects.h:42
bool _SetPix2(int32_t x, int32_t y, BYTE fgPix, BYTE bgPix)
void CheckInstabilityRange(int32_t tx, int32_t ty)
friend class DensityProvider
Definition: C4SolidMask.h:67
void Set(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iTX, int32_t iTY)
Definition: C4Rect.cpp:45

References C4Landscape::_GetPix(), C4Landscape::_SetPix2(), CheckConsistency(), C4Landscape::CheckInstabilityRange(), CNAT_Bottom, C4LArea::FirstObjectShapes(), C4Object::GetFixedX(), C4Object::GetSolidMaskPlane(), C4Object::GetY(), C4Rect::Hgt, iAttachingObjectsCapacity, iAttachingObjectsCount, C4Object::IsMoveableBySolidMask(), IsSomeVehicle(), Landscape, Last, MaskPut, MaskPutRect, MaskRemovalX, MaskRemovalY, MatBuffPitch, MCVehic, C4LArea::NextObjectShapes(), Objects, pForObject, ppAttachingObjects, Prev, pSolidMaskMatBuff, C4GameObjects::Sectors, C4TargetRect::Set(), C4Landscape::Transparent, C4TargetRect::tx, C4TargetRect::ty, C4Rect::Wdt, C4Rect::x, and C4Rect::y.

Referenced by C4Object::UpdateSolidMask(), and ~C4SolidMask().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RemoveSolidMasks()

void C4SolidMask::RemoveSolidMasks ( )
static

Definition at line 443 of file C4SolidMask.cpp.

444 {
445  C4Rect SolidMaskRect(0,0,::Landscape.GetWidth(),::Landscape.GetHeight());
446  C4SolidMask *pSolid;
447  for (pSolid = C4SolidMask::Last; pSolid; pSolid = pSolid->Prev)
448  {
449  pSolid->RemoveTemporary(SolidMaskRect);
450  }
451 }

References C4Landscape::GetHeight(), C4Landscape::GetWidth(), Landscape, Last, Prev, and RemoveTemporary().

Referenced by C4Game::ReloadDef(), C4Landscape::Save(), and C4Landscape::SaveDiff().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ RemoveTemporary()

void C4SolidMask::RemoveTemporary ( C4Rect  where)
protected

Definition at line 344 of file C4SolidMask.cpp.

345 {
346  if (!MaskPut || !pSolidMaskMatBuff) return;
347  where.Intersect(MaskPutRect);
348  // reput background pixels
349  for (int y = where.y; y < where.y + where.Hgt; ++y)
350  {
351  for (int x = where.x; x < where.x + where.Wdt; ++x)
352  {
354  // only if mask was used here
355  if (!IsSomeVehicle(*pPix)) //
356  {
357  // restore
358  assert(IsSomeVehicle(::Landscape.GetPix(x,y)));
360  }
361  }
362  }
363 }

References C4Landscape::_SetPix2Tmp(), C4Landscape::GetPix(), C4Rect::Hgt, C4Rect::Intersect(), IsSomeVehicle(), Landscape, MaskPut, MaskPutRect, MatBuffPitch, pSolidMaskMatBuff, C4Landscape::Transparent, C4TargetRect::tx, C4TargetRect::ty, C4Rect::Wdt, C4Rect::x, and C4Rect::y.

Referenced by CheckConsistency(), C4Landscape::DoRelights(), and RemoveSolidMasks().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Repair()

void C4SolidMask::Repair ( C4Rect  where)
protected

Definition at line 386 of file C4SolidMask.cpp.

387 {
388  if (!MaskPut || !pSolidMaskMatBuff) return;
389  where.Intersect(MaskPutRect);
390  // reput vehicle pixels
391  for (int y = where.y; y < where.y + where.Hgt; ++y)
392  {
393  for (int x = where.x; x < where.x + where.Wdt; ++x)
394  {
396  // only if mask was used here
397  if (!IsSomeVehicle(*pPix))
398  {
399  // record changed landscape in MatBuff
400  *pPix = ::Landscape.GetPix(x,y);
401  // put
403  }
404  }
405  }
406 }

References C4Landscape::GetPix(), C4Rect::Hgt, C4Rect::Intersect(), IsSomeVehicle(), Landscape, MaskMaterial, MaskPut, MaskPutRect, MatBuffPitch, pSolidMaskMatBuff, C4Landscape::SetPix2(), C4Landscape::Transparent, C4TargetRect::tx, C4TargetRect::ty, C4Rect::Wdt, C4Rect::x, and C4Rect::y.

Here is the call graph for this function:

◆ SetHalfVehicle()

void C4SolidMask::SetHalfVehicle ( bool  set)

Definition at line 503 of file C4SolidMask.cpp.

504 {
505  MaskMaterial = set ? MCHalfVehic : MCVehic;
506  // TODO: Redraw
507 }
BYTE MCHalfVehic
Definition: C4Material.cpp:38

References MaskMaterial, MCHalfVehic, and MCVehic.

Referenced by C4Object::SetHalfVehicleSolidMask().

Here is the caller graph for this function:

Friends And Related Function Documentation

◆ C4Landscape

friend class C4Landscape
friend

Definition at line 66 of file C4SolidMask.h.

◆ DensityProvider

friend class DensityProvider
friend

Definition at line 67 of file C4SolidMask.h.

Member Data Documentation

◆ First

C4SolidMask * C4SolidMask::First = nullptr
static

◆ iAttachingObjectsCapacity

int C4SolidMask::iAttachingObjectsCapacity
protected

Definition at line 38 of file C4SolidMask.h.

Referenced by C4SolidMask(), and Remove().

◆ iAttachingObjectsCount

int C4SolidMask::iAttachingObjectsCount
protected

Definition at line 38 of file C4SolidMask.h.

Referenced by C4SolidMask(), Put(), and Remove().

◆ Last

◆ MaskMaterial

BYTE C4SolidMask::MaskMaterial
protected

Definition at line 44 of file C4SolidMask.h.

Referenced by C4SolidMask(), Put(), PutTemporary(), Repair(), and SetHalfVehicle().

◆ MaskPut

bool C4SolidMask::MaskPut
protected

Definition at line 28 of file C4SolidMask.h.

Referenced by C4SolidMask(), Draw(), IsPut(), Put(), PutTemporary(), Remove(), RemoveTemporary(), and Repair().

◆ MaskPutRect

C4TargetRect C4SolidMask::MaskPutRect
protected

◆ MaskPutRotation

int C4SolidMask::MaskPutRotation
protected

Definition at line 29 of file C4SolidMask.h.

Referenced by C4SolidMask(), Draw(), C4SolidMask::DensityProvider::GetDensity(), and Put().

◆ MaskRemovalX

C4Real C4SolidMask::MaskRemovalX
protected

Definition at line 34 of file C4SolidMask.h.

Referenced by C4SolidMask(), Put(), and Remove().

◆ MaskRemovalY

int32_t C4SolidMask::MaskRemovalY
protected

Definition at line 35 of file C4SolidMask.h.

Referenced by C4SolidMask(), Put(), and Remove().

◆ MatBuffPitch

int C4SolidMask::MatBuffPitch
protected

◆ Next

◆ pForObject

C4Object* C4SolidMask::pForObject
protected

◆ ppAttachingObjects

class C4Object** C4SolidMask::ppAttachingObjects
protected

Definition at line 37 of file C4SolidMask.h.

Referenced by C4SolidMask(), Put(), Remove(), and ~C4SolidMask().

◆ Prev

◆ pSolidMaskMatBuff

BYTE* C4SolidMask::pSolidMaskMatBuff
protected

The documentation for this class was generated from the following files: