OpenClonk
C4Landscape Class Reference

#include <C4Landscape.h>

Classes

struct  P
 

Public Member Functions

 C4Landscape ()
 
 ~C4Landscape ()
 
void Default ()
 
void Clear (bool fClearMapCreator=true, bool fClearSky=true, bool fClearRenderer=true)
 
void Execute ()
 
void Synchronize ()
 
void Draw (C4TargetFacet &cgo, class C4FoWRegion *pLight=nullptr)
 
void ScenarioInit ()
 
void DrawMaterialRect (int32_t mat, int32_t tx, int32_t ty, int32_t wdt, int32_t hgt)
 
void RaiseTerrain (int32_t tx, int32_t ty, int32_t wdt)
 
void FindMatTop (int32_t mat, int32_t &x, int32_t &y, bool distant_first) const
 
BYTE GetMapIndex (int32_t iX, int32_t iY) const
 
BYTE GetBackMapIndex (int32_t iX, int32_t iY) const
 
bool Load (C4Group &hGroup, bool fLoadSky, bool fSavegame)
 
bool Save (C4Group &hGroup) const
 
bool SaveDiff (C4Group &hGroup, bool fSyncSave) const
 
bool SaveMap (C4Group &hGroup) const
 
bool SaveInitial ()
 
bool SaveTextures (C4Group &hGroup) const
 
bool Init (C4Group &hGroup, bool fOverloadCurrent, bool fLoadSky, bool &rfLoaded, bool fSavegame)
 
bool HasMap () const
 
bool MapToLandscape ()
 
bool ApplyDiff (C4Group &hGroup)
 
void SetMode (LandscapeMode iMode)
 
LandscapeMode GetMode () const
 
bool SetPix2 (int32_t x, int32_t y, BYTE fgPix, BYTE bgPix)
 
bool _SetPix2 (int32_t x, int32_t y, BYTE fgPix, BYTE bgPix)
 
void _SetPix2Tmp (int32_t x, int32_t y, BYTE fgPix, BYTE bgPix)
 
bool InsertMaterialOutsideLandscape (int32_t tx, int32_t ty, int32_t mdens)
 
bool InsertMaterial (int32_t mat, int32_t *tx, int32_t *ty, int32_t vx=0, int32_t vy=0, bool query_only=false)
 
bool InsertDeadMaterial (int32_t mat, int32_t tx, int32_t ty)
 
bool FindMatPath (int32_t &fx, int32_t &fy, int32_t ydir, int32_t mdens, int32_t mslide) const
 
bool FindMatSlide (int32_t &fx, int32_t &fy, int32_t ydir, int32_t mdens, int32_t mslide) const
 
bool FindMatPathPush (int32_t &fx, int32_t &fy, int32_t mdens, int32_t mslide, bool liquid) const
 
bool Incinerate (int32_t x, int32_t y, int32_t cause_player)
 
bool DrawBrush (int32_t iX, int32_t iY, int32_t iGrade, const char *szMaterial, const char *szTexture, const char *szBackMaterial, const char *szBackTexture)
 
bool DrawLine (int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2, int32_t iGrade, const char *szMaterial, const char *szTexture, const char *szBackMaterial, const char *szBackTexture)
 
bool DrawBox (int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2, int32_t iGrade, const char *szMaterial, const char *szTexture, const char *szBackMaterial, const char *szBackTexture)
 
bool DrawChunks (int32_t tx, int32_t ty, int32_t wdt, int32_t hgt, int32_t icntx, int32_t icnty, const char *szMaterial, const char *szTexture, bool bIFT)
 
bool DrawQuad (int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2, int32_t iX3, int32_t iY3, int32_t iX4, int32_t iY4, const char *szMaterial, const char *szBackMaterial, bool fDrawBridge)
 
bool DrawPolygon (int *vtcs, int length, const char *szMaterial, const char *szBackMaterial, bool fDrawBridge)
 
CStdPaletteGetPal () const
 
int32_t GetWidth () const
 
int32_t GetHeight () const
 
int32_t GetMapZoom () const
 
C4Real GetGravity () const
 
void SetGravity (C4Real g)
 
BYTE _GetPix (int32_t x, int32_t y) const
 
BYTE GetPix (int32_t x, int32_t y) const
 
int32_t _GetMat (int32_t x, int32_t y) const
 
int32_t _GetDensity (int32_t x, int32_t y) const
 
int32_t _GetPlacement (int32_t x, int32_t y) const
 
int32_t GetMat (int32_t x, int32_t y) const
 
int32_t GetDensity (int32_t x, int32_t y) const
 
int32_t GetPlacement (int32_t x, int32_t y) const
 
BYTE _GetBackPix (int32_t x, int32_t y) const
 
BYTE GetBackPix (int32_t x, int32_t y) const
 
int32_t _GetBackMat (int32_t x, int32_t y) const
 
int32_t _GetBackDensity (int32_t x, int32_t y) const
 
int32_t _GetBackPlacement (int32_t x, int32_t y) const
 
int32_t GetBackMat (int32_t x, int32_t y) const
 
int32_t GetBackDensity (int32_t x, int32_t y) const
 
int32_t GetBackPlacement (int32_t x, int32_t y) const
 
bool GetLight (int32_t x, int32_t y)
 
bool _GetLight (int32_t x, int32_t y)
 
bool _FastSolidCheck (int32_t x, int32_t y) const
 
int32_t GetPixMat (BYTE byPix) const
 
int32_t GetPixDensity (BYTE byPix) const
 
bool _PathFree (int32_t x, int32_t y, int32_t x2, int32_t y2) const
 
int32_t GetMatHeight (int32_t x, int32_t y, int32_t iYDir, int32_t iMat, int32_t iMax) const
 
int32_t AreaSolidCount (int32_t x, int32_t y, int32_t wdt, int32_t hgt) const
 
int32_t ExtractMaterial (int32_t fx, int32_t fy, bool distant_first)
 
bool DrawMap (int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, const char *szMapDef, bool ignoreSky=false)
 
bool ClipRect (int32_t &rX, int32_t &rY, int32_t &rWdt, int32_t &rHgt) const
 
bool DrawDefMap (int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, const char *szMapDef, bool ignoreSky=false)
 
bool SetModulation (DWORD dwWithClr)
 
DWORD GetModulation () const
 
bool PostInitMap ()
 
bool ReplaceMapColor (BYTE iOldIndex, BYTE iNewIndex)
 
bool SetTextureIndex (const char *szMatTex, BYTE iNewIndex, bool fInsert)
 
void SetMapChanged ()
 
void HandleTexMapUpdate ()
 
void UpdatePixMaps ()
 
bool DoRelights ()
 
void RemoveUnusedTexMapEntries ()
 
class C4SkyGetSky ()
 
bool HasFoW () const
 
class C4FoWGetFoW ()
 
int32_t GetMatCount (int material) const
 
int32_t GetEffectiveMatCount (int material) const
 
int32_t DigFreeShape (int *vtcs, int length, C4Object *by_object=nullptr, bool no_dig2objects=false, bool no_instability_check=false)
 
void BlastFreeShape (int *vtcs, int length, C4Object *by_object=nullptr, int32_t by_player=NO_OWNER, int32_t iMaxDensity=C4M_Vehicle)
 
void ClearFreeRect (int32_t tx, int32_t ty, int32_t wdt, int32_t hgt)
 
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)
 
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)
 
void ShakeFree (int32_t tx, int32_t ty, int32_t rad)
 
void BlastFree (int32_t tx, int32_t ty, int32_t rad, int32_t caused_by=NO_OWNER, C4Object *by_object=nullptr, int32_t iMaxDensity=C4M_Vehicle)
 
void CheckInstabilityRange (int32_t tx, int32_t ty)
 
bool CheckInstability (int32_t tx, int32_t ty, int32_t recursion_count=0)
 
bool ClearPix (int32_t tx, int32_t ty)
 
void ClearPointers (C4Object *pObj)
 
void CompileFunc (StdCompiler *pComp)
 

Static Public Member Functions

static int32_t FastSolidCheckNextX (int32_t x)
 

Static Public Attributes

static const uint8_t Transparent = C4M_MaxTexIndex
 

Detailed Description

Definition at line 37 of file C4Landscape.h.

Constructor & Destructor Documentation

◆ C4Landscape()

C4Landscape::C4Landscape ( )

Definition at line 189 of file C4Landscape.cpp.

190  : p(new P)
191 {
192  Default();
193 }

References Default().

Here is the call graph for this function:

◆ ~C4Landscape()

C4Landscape::~C4Landscape ( )

Definition at line 195 of file C4Landscape.cpp.

196 {
197  Clear();
198 }
void Clear(bool fClearMapCreator=true, bool fClearSky=true, bool fClearRenderer=true)

References Clear().

Here is the call graph for this function:

Member Function Documentation

◆ _FastSolidCheck()

bool C4Landscape::_FastSolidCheck ( int32_t  x,
int32_t  y 
) const

Definition at line 3823 of file C4Landscape.cpp.

3824 {
3825  return p->PixCnt[(x / 17) * p->PixCntPitch + (y / 15)] > 0;
3826 }

References CPolyEdge::x, and CPolyEdge::y.

Referenced by C4FoWLightSection::Update().

Here is the caller graph for this function:

◆ _GetBackDensity()

int32_t C4Landscape::_GetBackDensity ( int32_t  x,
int32_t  y 
) const

Definition at line 3788 of file C4Landscape.cpp.

3789 {
3790  return p->Pix2Dens[_GetBackPix(x, y)];
3791 }
BYTE _GetBackPix(int32_t x, int32_t y) const

References _GetBackPix(), CPolyEdge::x, and CPolyEdge::y.

Here is the call graph for this function:

◆ _GetBackMat()

int32_t C4Landscape::_GetBackMat ( int32_t  x,
int32_t  y 
) const

Definition at line 3783 of file C4Landscape.cpp.

3784 {
3785  return p->Pix2Mat[_GetBackPix(x, y)];
3786 }

References _GetBackPix(), CPolyEdge::x, and CPolyEdge::y.

Here is the call graph for this function:

◆ _GetBackPix()

BYTE C4Landscape::_GetBackPix ( int32_t  x,
int32_t  y 
) const

Definition at line 3752 of file C4Landscape.cpp.

3753 {
3754 #ifdef _DEBUG
3755  if (x < 0 || y < 0 || x >= p->Width || y >= p->Height) { BREAKPOINT_HERE; }
3756 #endif
3757  return p->Surface8Bkg->_GetPix(x, y);
3758 }
#define BREAKPOINT_HERE

References BREAKPOINT_HERE, CPolyEdge::x, and CPolyEdge::y.

Referenced by _GetBackDensity(), _GetBackMat(), _GetBackPlacement(), and _GetLight().

Here is the caller graph for this function:

◆ _GetBackPlacement()

int32_t C4Landscape::_GetBackPlacement ( int32_t  x,
int32_t  y 
) const

Definition at line 3793 of file C4Landscape.cpp.

3794 {
3795  return p->Pix2Place[_GetBackPix(x, y)];
3796 }

References _GetBackPix(), CPolyEdge::x, and CPolyEdge::y.

Here is the call graph for this function:

◆ _GetDensity()

int32_t C4Landscape::_GetDensity ( int32_t  x,
int32_t  y 
) const

Definition at line 3727 of file C4Landscape.cpp.

3728 {
3729  return p->Pix2Dens[_GetPix(x, y)];
3730 }
BYTE _GetPix(int32_t x, int32_t y) const

References _GetPix(), CPolyEdge::x, and CPolyEdge::y.

Referenced by C4Landscape::P::UpdatePixCnt().

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

◆ _GetLight()

bool C4Landscape::_GetLight ( int32_t  x,
int32_t  y 
)

Definition at line 3818 of file C4Landscape.cpp.

3819 {
3820  return _GetBackPix(x, y) == 0 || p->Pix2Light[_GetPix(x, y)];
3821 }

References _GetBackPix(), _GetPix(), CPolyEdge::x, and CPolyEdge::y.

Here is the call graph for this function:

◆ _GetMat()

int32_t C4Landscape::_GetMat ( int32_t  x,
int32_t  y 
) const

Definition at line 3722 of file C4Landscape.cpp.

3723 {
3724  return p->Pix2Mat[_GetPix(x, y)];
3725 }

References _GetPix(), CPolyEdge::x, and CPolyEdge::y.

Referenced by C4Landscape::P::DoScan(), C4Landscape::P::ExecuteScan(), GetMatHeight(), InsertDeadMaterial(), and C4Landscape::P::UpdateMatCnt().

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

◆ _GetPix()

BYTE C4Landscape::_GetPix ( int32_t  x,
int32_t  y 
) const

Definition at line 3691 of file C4Landscape.cpp.

3692 {
3693 #ifdef _DEBUG
3694  if (x < 0 || y < 0 || x >= p->Width || y >= p->Height) { BREAKPOINT_HERE; }
3695 #endif
3696  return p->Surface8->_GetPix(x, y);
3697 }

References BREAKPOINT_HERE, CPolyEdge::x, and CPolyEdge::y.

Referenced by _GetDensity(), _GetLight(), _GetMat(), _GetPlacement(), _SetPix2(), C4Landscape::P::DoScan(), InsertDeadMaterial(), C4SolidMask::Put(), C4SolidMask::Remove(), SetPix2(), and C4LandscapeRenderGL::Update().

Here is the caller graph for this function:

◆ _GetPlacement()

int32_t C4Landscape::_GetPlacement ( int32_t  x,
int32_t  y 
) const

Definition at line 3732 of file C4Landscape.cpp.

3733 {
3734  return p->Pix2Place[_GetPix(x, y)];
3735 }

References _GetPix(), CPolyEdge::x, and CPolyEdge::y.

Referenced by C4LandscapeRenderGL::Update().

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

◆ _PathFree()

bool C4Landscape::_PathFree ( int32_t  x,
int32_t  y,
int32_t  x2,
int32_t  y2 
) const

Definition at line 3837 of file C4Landscape.cpp.

3838 {
3839  x /= 17; y /= 15; x2 /= 17; y2 /= 15;
3840  while (x != x2 && y != y2)
3841  {
3842  if (p->PixCnt[x * p->PixCntPitch + y])
3843  return false;
3844  if (x > x2) x--; else x++;
3845  if (y > y2) y--; else y++;
3846  }
3847  if (x != x2)
3848  do
3849  {
3850  if (p->PixCnt[x * p->PixCntPitch + y])
3851  return false;
3852  if (x > x2) x--; else x++;
3853  } while (x != x2);
3854  else
3855  while (y != y2)
3856  {
3857  if (p->PixCnt[x * p->PixCntPitch + y])
3858  return false;
3859  if (y > y2) y--; else y++;
3860  }
3861  return !p->PixCnt[x * p->PixCntPitch + y];
3862 }

References CPolyEdge::x, and CPolyEdge::y.

◆ _SetPix2()

bool C4Landscape::_SetPix2 ( int32_t  x,
int32_t  y,
BYTE  fgPix,
BYTE  bgPix 
)

Definition at line 798 of file C4Landscape.cpp.

799 {
800  if (Config.General.DebugRec)
801  {
802  C4RCSetPix rc;
803  rc.x = x; rc.y = y; rc.clr = fgPix; rc.bgClr = fgPix;
804  AddDbgRec(RCT_SetPix, &rc, sizeof(rc));
805  }
806  assert(x >= 0 && y >= 0 && x < GetWidth() && y < GetHeight());
807  // get pixel and resolve transparency to already existing pixel
808  BYTE opix = _GetPix(x, y);
809  if (fgPix == Transparent) fgPix = opix;
810  if (bgPix == Transparent) bgPix = p->Surface8Bkg->_GetPix(x, y);
811  // check pixel
812  if (fgPix == opix && bgPix == p->Surface8Bkg->_GetPix(x, y)) return true;
813  // count pixels
814  if (p->Pix2Dens[fgPix])
815  {
816  if (!p->Pix2Dens[opix]) p->PixCnt[(y / 15) + (x / 17) * p->PixCntPitch]++;
817  }
818  else
819  {
820  if (p->Pix2Dens[opix]) p->PixCnt[(y / 15) + (x / 17) * p->PixCntPitch]--;
821  }
822  // count material
823  assert(!fgPix || MatValid(p->Pix2Mat[fgPix]));
824  int32_t omat = p->Pix2Mat[opix], nmat = p->Pix2Mat[fgPix];
825  if (opix) p->MatCount[omat]--;
826  if (fgPix) p->MatCount[nmat]++;
827  // count effective material
828  if (omat != nmat)
829  {
830  if (fgPix && ::MaterialMap.Map[nmat].MinHeightCount)
831  {
832  // Check for material above & below
833  int iMinHeight = ::MaterialMap.Map[nmat].MinHeightCount,
834  iBelow = GetMatHeight(x, y + 1, +1, nmat, iMinHeight),
835  iAbove = GetMatHeight(x, y - 1, -1, nmat, iMinHeight);
836  // Will be above treshold?
837  if (iBelow + iAbove + 1 >= iMinHeight)
838  {
839  int iChange = 1;
840  // Check for heights below threshold
841  if (iBelow < iMinHeight) iChange += iBelow;
842  if (iAbove < iMinHeight) iChange += iAbove;
843  // Change
844  p->EffectiveMatCount[nmat] += iChange;
845  }
846  }
847  if (opix && ::MaterialMap.Map[omat].MinHeightCount)
848  {
849  // Check for material above & below
850  int iMinHeight = ::MaterialMap.Map[omat].MinHeightCount,
851  iBelow = GetMatHeight(x, y + 1, +1, omat, iMinHeight),
852  iAbove = GetMatHeight(x, y - 1, -1, omat, iMinHeight);
853  // Not already below threshold?
854  if (iBelow + iAbove + 1 >= iMinHeight)
855  {
856  int iChange = 1;
857  // Check for heights that will get below threshold
858  if (iBelow < iMinHeight) iChange += iBelow;
859  if (iAbove < iMinHeight) iChange += iAbove;
860  // Change
861  p->EffectiveMatCount[omat] -= iChange;
862  }
863  }
864  }
865  // set 8bpp-surface only!
866  p->Surface8->SetPix(x, y, fgPix);
867  p->Surface8Bkg->SetPix(x, y, bgPix);
868  // note for relight
869  if (p->pLandscapeRender)
870  {
871  C4Rect CheckRect = p->pLandscapeRender->GetAffectedRect(C4Rect(x, y, 1, 1));
872  for (int32_t i = 0; i < C4LS_MaxRelights; i++)
873  if (!p->Relights[i].Wdt || p->Relights[i].Overlap(CheckRect) || i + 1 >= C4LS_MaxRelights)
874  {
875  p->Relights[i].Add(CheckRect);
876  break;
877  }
878  // Invalidate FoW
879  if (p->pFoW)
880  p->pFoW->Invalidate(CheckRect);
881  }
882  // success
883  return true;
884 }
C4Config Config
Definition: C4Config.cpp:930
const int32_t C4LS_MaxRelights
Definition: C4Landscape.h:27
C4MaterialMap MaterialMap
Definition: C4Material.cpp:974
bool MatValid(int32_t mat)
Definition: C4Material.h:210
void AddDbgRec(C4RecordChunkType eType, const void *pData, int iSize)
Definition: C4Record.cpp:32
BYTE bgClr
Definition: C4Record.h:126
@ RCT_SetPix
Definition: C4Record.h:56
BYTE clr
Definition: C4Record.h:125
uint8_t BYTE
int32_t DebugRec
Definition: C4Config.h:63
C4ConfigGeneral General
Definition: C4Config.h:255
int32_t GetWidth() const
static const uint8_t Transparent
Definition: C4Landscape.h:50
int32_t GetHeight() const
int32_t GetMatHeight(int32_t x, int32_t y, int32_t iYDir, int32_t iMat, int32_t iMax) const
int32_t MinHeightCount
Definition: C4Material.h:130
C4Material * Map
Definition: C4Material.h:169
Definition: C4Rect.h:28

References _GetPix(), AddDbgRec(), C4RCSetPix::bgClr, C4LS_MaxRelights, C4RCSetPix::clr, Config, C4ConfigGeneral::DebugRec, C4Config::General, GetHeight(), GetMatHeight(), GetWidth(), C4MaterialMap::Map, MaterialMap, MatValid(), C4MaterialCore::MinHeightCount, RCT_SetPix, Transparent, C4RCSetPix::x, and C4RCSetPix::y.

Referenced by C4TextureShape::Draw(), C4SolidMask::Remove(), and SetPix2().

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

◆ _SetPix2Tmp()

void C4Landscape::_SetPix2Tmp ( int32_t  x,
int32_t  y,
BYTE  fgPix,
BYTE  bgPix 
)

Definition at line 886 of file C4Landscape.cpp.

887 {
888  // set 8bpp-surface only!
889  assert(x >= 0 && y >= 0 && x < GetWidth() && y < GetHeight());
890  if (fgPix != Transparent) p->Surface8->SetPix(x, y, fgPix);
891  if (bgPix != Transparent) p->Surface8Bkg->SetPix(x, y, bgPix);
892 }

References GetHeight(), GetWidth(), and Transparent.

Referenced by C4SolidMask::PutTemporary(), and C4SolidMask::RemoveTemporary().

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

◆ ApplyDiff()

bool C4Landscape::ApplyDiff ( C4Group hGroup)

Definition at line 1901 of file C4Landscape.cpp.

1902 {
1903  std::unique_ptr<CSurface8> pDiff, pDiffBkg;
1904  // Load diff landscape from group
1905  pDiff = GroupReadSurface8(hGroup, C4CFN_DiffLandscape);
1906  pDiffBkg = GroupReadSurface8(hGroup, C4CFN_DiffLandscapeBkg);
1907  if (pDiff == nullptr && pDiffBkg == nullptr) return false;
1908 
1909  // convert all pixels: keep if same material; re-set if different material
1910  BYTE byPix;
1911  for (int32_t y = 0; y < GetHeight(); ++y) for (int32_t x = 0; x < GetWidth(); ++x)
1912  {
1913  if (pDiff && pDiff->GetPix(x, y) != C4M_MaxTexIndex)
1914  if (p->Surface8->_GetPix(x, y) != (byPix = pDiff->_GetPix(x, y)))
1915  // material has changed here: readjust with new texture
1916  p->Surface8->SetPix(x, y, byPix);
1917  if (pDiffBkg && pDiffBkg->GetPix(x, y) != C4M_MaxTexIndex)
1918  if (p->Surface8Bkg->_GetPix(x, y) != (byPix = pDiffBkg->_GetPix(x, y)))
1919  p->Surface8Bkg->_SetPix(x, y, byPix);
1920  }
1921 
1922  // done
1923  return true;
1924 }
#define C4CFN_DiffLandscape
Definition: C4Components.h:63
#define C4CFN_DiffLandscapeBkg
Definition: C4Components.h:64
const int C4M_MaxTexIndex
Definition: C4Constants.h:51

◆ AreaSolidCount()

int32_t C4Landscape::AreaSolidCount ( int32_t  x,
int32_t  y,
int32_t  wdt,
int32_t  hgt 
) const

Definition at line 3328 of file C4Landscape.cpp.

3329 {
3330  int32_t cx, cy, ascnt = 0;
3331  for (cy = y; cy < y + hgt; cy++)
3332  for (cx = x; cx < x + wdt; cx++)
3333  if (GBackSolid(cx, cy))
3334  ascnt++;
3335  return ascnt;
3336 }
bool GBackSolid(int32_t x, int32_t y)
Definition: C4Landscape.h:229

References GBackSolid(), CPolyEdge::x, and CPolyEdge::y.

Referenced by ConstructionCheck().

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

◆ BlastFree()

void C4Landscape::BlastFree ( int32_t  tx,
int32_t  ty,
int32_t  rad,
int32_t  caused_by = NO_OWNER,
C4Object by_object = nullptr,
int32_t  iMaxDensity = C4M_Vehicle 
)

Definition at line 507 of file C4Landscape.cpp.

508 {
509  std::vector<int32_t> vertices(GetRoundPolygon(tx, ty, rad, 30));
510  BlastFreeShape(&vertices[0], vertices.size(), by_object, caused_by, iMaxDensity);
511 }
void BlastFreeShape(int *vtcs, int length, C4Object *by_object=nullptr, int32_t by_player=NO_OWNER, int32_t iMaxDensity=C4M_Vehicle)

◆ BlastFreeShape()

void C4Landscape::BlastFreeShape ( int *  vtcs,
int  length,
C4Object by_object = nullptr,
int32_t  by_player = NO_OWNER,
int32_t  iMaxDensity = C4M_Vehicle 
)

Definition at line 597 of file C4Landscape.cpp.

598 {
599  C4MaterialList *MaterialContents = nullptr;
600 
601  C4Rect BoundingBox = getBoundingBox(vtcs, length);
602 
603  // Remember any collectible objects in area
604  std::unique_ptr<C4ValueArray> dig_objects(p->PrepareFreeShape(BoundingBox, by_object));
605 
606  uint8_t *pblast_tbl = nullptr, blast_tbl[C4M_MaxTexIndex];
607  if (iMaxDensity < C4M_Vehicle)
608  {
609  for (int32_t i = 0; i < C4M_MaxTexIndex; ++i) blast_tbl[i] = (GetPixDensity(i) <= iMaxDensity);
610  pblast_tbl = blast_tbl;
611  }
612 
613  if (by_object)
614  {
615  if (!by_object->MaterialContents)
616  by_object->MaterialContents = new C4MaterialList;
617  p->ForPolygon(this, vtcs, length / 2, [this](int32_t x, int32_t y) { return p->BlastFreePix(this, x, y); }, by_object->MaterialContents, 0, 0, pblast_tbl);
618  }
619  else
620  {
621  MaterialContents = new C4MaterialList;
622  p->ForPolygon(this, vtcs, length / 2, [this](int32_t x, int32_t y) { return p->BlastFreePix(this, x, y); }, MaterialContents, iMaxDensity);
623  }
624 
625  // create objects from the material
626  C4MaterialList *mat_list = nullptr;
627  if (by_object)
628  mat_list = by_object->MaterialContents;
629  else
630  mat_list = MaterialContents;
631 
632  int32_t tx = BoundingBox.GetMiddleX(), ty = BoundingBox.GetMiddleY();
633  p->BlastMaterial2Objects(tx, ty, mat_list, by_player, (BoundingBox.Wdt + BoundingBox.Hgt) / 4, dig_objects.get());
634 
635  if (MaterialContents) delete MaterialContents;
636 
637  // Do callbacks to digger for objects that are now dug free
638  p->PostFreeShape(dig_objects.get(), by_object);
639 }
const int32_t C4M_Vehicle
Definition: C4Constants.h:171
int32_t GetPixDensity(BYTE byPix) const
C4MaterialList * MaterialContents
Definition: C4Object.h:152
int32_t GetMiddleX() const
Definition: C4Rect.h:56
int32_t Hgt
Definition: C4Rect.h:30
int32_t Wdt
Definition: C4Rect.h:30
int32_t GetMiddleY() const
Definition: C4Rect.h:57

◆ CheckInstability()

bool C4Landscape::CheckInstability ( int32_t  tx,
int32_t  ty,
int32_t  recursion_count = 0 
)

Definition at line 894 of file C4Landscape.cpp.

895 {
896  int32_t mat = GetMat(tx, ty);
897  if (MatValid(mat)) {
898  const C4Material &material = MaterialMap.Map[mat];
899  if (material.Instable)
900  return ::MassMover.Create(tx, ty);
901  // Get rid of single pixels
902  else if (DensitySolid(material.Density) && !material.KeepSinglePixels && recursion_count < 10)
903  if ((!::GBackSolid(tx, ty + 1)) + (!::GBackSolid(tx, ty - 1)) + (!::GBackSolid(tx + 1, ty)) + (!::GBackSolid(tx - 1, ty)) >= 3)
904  {
905  if (!ClearPix(tx, ty)) return false;
906  // Diggable material drops; other material just gets removed
907  if (material.DigFree) ::PXS.Create(mat, itofix(tx), itofix(ty));
908  // check other pixels around this
909  // Note this cannot lead to an endless recursion (unless you do funny stuff like e.g. set DigFree=1 in material Tunnel).
910  // Check recursion anyway, because very large strips of single pixel width might cause sufficient recursion to crash
911  CheckInstability(tx + 1, ty, ++recursion_count);
912  CheckInstability(tx - 1, ty, recursion_count);
913  CheckInstability(tx, ty - 1, recursion_count);
914  CheckInstability(tx, ty + 1, recursion_count);
915  return true;
916  }
917  }
918  return false;
919 }
bool DensitySolid(int32_t dens)
Definition: C4Landscape.h:196
C4MassMoverSet MassMover
C4PXSSystem PXS
Definition: C4PXS.cpp:423
C4Fixed itofix(int32_t x)
Definition: C4Real.h:261
int32_t GetMat(int32_t x, int32_t y) const
bool ClearPix(int32_t tx, int32_t ty)
bool CheckInstability(int32_t tx, int32_t ty, int32_t recursion_count=0)
bool Create(int32_t x, int32_t y, bool fExecute=false)
Definition: C4MassMover.cpp:70
bool KeepSinglePixels
Definition: C4Material.h:132
int32_t Density
Definition: C4Material.h:92
int32_t DigFree
Definition: C4Material.h:94
int32_t Instable
Definition: C4Material.h:102
bool Create(int32_t mat, C4Real ix, C4Real iy, C4Real ixdir=Fix0, C4Real iydir=Fix0)
Definition: C4PXS.cpp:175

References ClearPix(), C4PXSSystem::Create(), C4MassMoverSet::Create(), C4MaterialCore::Density, DensitySolid(), C4MaterialCore::DigFree, GBackSolid(), GetMat(), C4MaterialCore::Instable, itofix(), C4MaterialCore::KeepSinglePixels, C4MaterialMap::Map, MassMover, MaterialMap, MatValid(), and PXS.

Referenced by CheckInstabilityRange().

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

◆ CheckInstabilityRange()

void C4Landscape::CheckInstabilityRange ( int32_t  tx,
int32_t  ty 
)

Definition at line 921 of file C4Landscape.cpp.

922 {
923  if (!CheckInstability(tx, ty))
924  {
925  CheckInstability(tx, ty - 1);
926  CheckInstability(tx, ty - 2);
927  CheckInstability(tx - 1, ty);
928  CheckInstability(tx + 1, ty);
929  }
930 }

References CheckInstability().

Referenced by C4Landscape::P::BlastFreePix(), C4Landscape::P::DigFreePix(), C4Landscape::P::DoScan(), ExtractMaterial(), C4SolidMask::Remove(), and C4Landscape::P::ShakeFreePix().

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

◆ Clear()

void C4Landscape::Clear ( bool  fClearMapCreator = true,
bool  fClearSky = true,
bool  fClearRenderer = true 
)

Definition at line 1357 of file C4Landscape.cpp.

1358 {
1359  if (fClearMapCreator) { p->pMapCreator.reset(); }
1360  // clear sky
1361  if (fClearSky) p->Sky.Clear();
1362  // clear surfaces, if assigned
1363  if (fClearRenderer) { p->pLandscapeRender.reset(); }
1364  p->TopRowPix.clear();
1365  p->BottomRowPix.clear();
1366  p->LeftColPix.clear();
1367  p->RightColPix.clear();
1368  p->Surface8.reset();
1369  p->Surface8Bkg.reset();
1370  p->Map.reset();
1371  p->MapBkg.reset();
1372  // clear initial landscape
1373  p->pInitial.reset();
1374  p->pInitialBkg.reset();
1375  p->pFoW.reset();
1376  // clear relight array
1377  for (auto &relight : p->Relights)
1378  relight.Default();
1379  // clear scan
1380  p->ScanX = 0;
1381  p->mode = LandscapeMode::Undefined;
1382  // clear pixel count
1383  p->PixCnt.clear();
1384  p->PixCntPitch = 0;
1385  // clear bridge material conversion temp buffers
1386  for (auto &conv : p->BridgeMatConversion)
1387  conv.reset();
1388 }

References Undefined.

Referenced by C4Game::Clear(), and ~C4Landscape().

Here is the caller graph for this function:

◆ ClearFreeRect()

void C4Landscape::ClearFreeRect ( int32_t  tx,
int32_t  ty,
int32_t  wdt,
int32_t  hgt 
)

Definition at line 486 of file C4Landscape.cpp.

487 {
488  std::vector<int32_t> vertices(GetRectangle(tx, ty, wdt, hgt));
489  C4Rect r(tx, ty, wdt, hgt);
490  p->PrepareChange(this, r, false);
491  p->ForPolygon(this, &vertices[0], vertices.size() / 2, [this](int32_t x, int32_t y) { return ClearPix(x, y); });
492  p->FinishChange(this, r, false);
493 }

◆ ClearPix()

bool C4Landscape::ClearPix ( int32_t  tx,
int32_t  ty 
)

Definition at line 774 of file C4Landscape.cpp.

775 {
776  // Replace pixel with background pixel
777  BYTE bkgPix = p->Surface8Bkg->GetPix(tx, ty);
778  return SetPix2(tx, ty, bkgPix, bkgPix);
779 }
bool SetPix2(int32_t x, int32_t y, BYTE fgPix, BYTE bgPix)

References SetPix2().

Referenced by C4Landscape::P::BlastFreePix(), CheckInstability(), C4Landscape::P::DigFreePix(), C4Landscape::P::DigFreePixNoInstability(), ExtractMaterial(), C4MaterialMap::mrfCorrode(), and C4Landscape::P::ShakeFreePix().

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

◆ ClearPointers()

void C4Landscape::ClearPointers ( C4Object pObj)

Definition at line 781 of file C4Landscape.cpp.

782 {
783  if (p->pFoW) p->pFoW->Remove(pObj);
784 }

Referenced by C4Game::ClearPointers().

Here is the caller graph for this function:

◆ ClipRect()

bool C4Landscape::ClipRect ( int32_t &  rX,
int32_t &  rY,
int32_t &  rWdt,
int32_t &  rHgt 
) const

Definition at line 4027 of file C4Landscape.cpp.

4028 {
4029  // clip by bounds
4030  if (rX < 0) { rWdt += rX; rX = 0; }
4031  if (rY < 0) { rHgt += rY; rY = 0; }
4032  int32_t iOver;
4033 
4034  iOver = rX + rWdt - GetWidth();
4035  if (iOver > 0)
4036  rWdt -= iOver;
4037 
4038  iOver = rY + rHgt - GetHeight();
4039  if (iOver > 0)
4040  rHgt -= iOver;
4041 
4042  // anything left inside the bounds?
4043  return rWdt > 0 && rHgt > 0;
4044 }

References GetHeight(), and GetWidth().

Referenced by DrawDefMap(), and DrawMap().

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

◆ CompileFunc()

void C4Landscape::CompileFunc ( StdCompiler pComp)

Definition at line 1390 of file C4Landscape.cpp.

1391 {
1392  pComp->Value(mkNamingAdapt(p->MapSeed, "MapSeed", 0));
1393  pComp->Value(mkNamingAdapt(mkCastIntAdapt(p->Gravity), "Gravity", DefaultGravAccel));
1394  pComp->Value(mkNamingAdapt(p->Modulation, "MatModulation", 0U));
1395  pComp->Value(mkNamingAdapt(mkCastIntAdapt(p->mode), "Mode", LandscapeMode::Undefined));
1396 
1397  if (pComp->isDeserializer())
1398  {
1399  int32_t ambient_brightness;
1400  pComp->Value(mkNamingAdapt(ambient_brightness, "AmbientBrightness", 255));
1401  if (p->pFoW) p->pFoW->Ambient.SetBrightness(ambient_brightness / static_cast<double>(255));
1402  }
1403  else
1404  {
1405  if (p->pFoW)
1406  {
1407  int32_t ambient_brightness = static_cast<int32_t>(p->pFoW->Ambient.GetBrightness() * 255 + 0.5);
1408  pComp->Value(mkNamingAdapt(ambient_brightness, "AmbientBrightness", 255));
1409  }
1410  }
1411 }
const C4Real DefaultGravAccel
Definition: C4Movement.cpp:41
StdCastAdapt< T, int32_t > mkCastIntAdapt(T &rValue)
Definition: StdAdaptors.h:281
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
Definition: StdAdaptors.h:92
void Value(const T &rStruct)
Definition: StdCompiler.h:161
virtual bool isDeserializer()
Definition: StdCompiler.h:53

References DefaultGravAccel, StdCompiler::isDeserializer(), mkCastIntAdapt(), mkNamingAdapt(), Undefined, and StdCompiler::Value().

Here is the call graph for this function:

◆ Default()

void C4Landscape::Default ( )

Definition at line 1926 of file C4Landscape.cpp.

1927 {
1928  p = std::make_unique<P>();
1929 }

Referenced by C4Landscape(), and C4Game::Default().

Here is the caller graph for this function:

◆ DigFree()

int32_t C4Landscape::DigFree ( int32_t  tx,
int32_t  ty,
int32_t  rad,
C4Object by_object = nullptr,
bool  no_dig2objects = false,
bool  no_instability_check = false 
)

Definition at line 501 of file C4Landscape.cpp.

502 {
503  std::vector<int32_t> vertices(GetRoundPolygon(tx, ty, rad, 80));
504  return DigFreeShape(&vertices[0], vertices.size(), by_object, no_dig2objects, no_instability_check);
505 }
int32_t DigFreeShape(int *vtcs, int length, C4Object *by_object=nullptr, bool no_dig2objects=false, bool no_instability_check=false)

◆ DigFreeRect()

int32_t C4Landscape::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 
)

Definition at line 495 of file C4Landscape.cpp.

496 {
497  std::vector<int32_t> vertices(GetRectangle(tx, ty, wdt, hgt));
498  return DigFreeShape(&vertices[0], vertices.size(), by_object, no_dig2objects, no_instability_check);
499 }

Referenced by C4Game::CreateObjectConstruction().

Here is the caller graph for this function:

◆ DigFreeShape()

int32_t C4Landscape::DigFreeShape ( int *  vtcs,
int  length,
C4Object by_object = nullptr,
bool  no_dig2objects = false,
bool  no_instability_check = false 
)

Definition at line 554 of file C4Landscape.cpp.

555 {
556  using namespace std::placeholders;
557 
558  C4Rect BoundingBox = getBoundingBox(vtcs, length);
559  int32_t amount;
560 
561  // Remember any collectible objects in area
562  std::unique_ptr<C4ValueArray> dig_objects(p->PrepareFreeShape(BoundingBox, by_object));
563 
564  std::function<bool(int32_t, int32_t)> callback;
565  if (no_instability_check)
566  callback = [this](int32_t x, int32_t y) { return p->DigFreePixNoInstability(this, x, y); };
567  else
568  callback = [this](int32_t x, int32_t y) { return p->DigFreePix(this, x, y); };
569 
570  if (by_object)
571  {
572  if (!by_object->MaterialContents)
573  by_object->MaterialContents = new C4MaterialList;
574  amount = p->ForPolygon(this, vtcs, length / 2, callback, by_object->MaterialContents);
575  }
576  else
577  amount = p->ForPolygon(this, vtcs, length / 2, callback, nullptr);
578 
579  // create objects from the material
580  if (!::Game.iTick5)
581  {
582  if (!no_dig2objects)
583  if (by_object)
584  if (by_object->MaterialContents)
585  {
586  int32_t tx = BoundingBox.GetMiddleX(), ty = BoundingBox.GetBottom();
587  p->DigMaterial2Objects(tx, ty, by_object->MaterialContents, by_object);
588  }
589  }
590 
591  // Do callbacks to digger for objects that are now dug free
592  p->PostFreeShape(dig_objects.get(), by_object);
593 
594  return amount;
595 }
C4Game Game
Definition: C4Globals.cpp:52
int32_t iTick5
Definition: C4Game.h:130
int32_t GetBottom() const
Definition: C4Rect.h:58

◆ DoRelights()

bool C4Landscape::DoRelights ( )

Definition at line 390 of file C4Landscape.cpp.

391 {
392  if (!p->pLandscapeRender) return true;
393  for (int32_t i = 0; i < C4LS_MaxRelights; i++)
394  {
395  if (!p->Relights[i].Wdt)
396  break;
397  // Remove all solid masks in the (twice!) extended region around the change
398  C4Rect SolidMaskRect = p->pLandscapeRender->GetAffectedRect(p->Relights[i]);
399  C4SolidMask * pSolid;
400  for (pSolid = C4SolidMask::Last; pSolid; pSolid = pSolid->Prev)
401  pSolid->RemoveTemporary(SolidMaskRect);
402  // Perform the update
403  p->pLandscapeRender->Update(p->Relights[i], this);
404  if (p->pFoW) p->pFoW->Ambient.UpdateFromLandscape(*this, p->Relights[i]);
405  // Restore Solidmasks
406  for (pSolid = C4SolidMask::First; pSolid; pSolid = pSolid->Next)
407  pSolid->PutTemporary(SolidMaskRect);
409  // Clear slot
410  p->Relights[i].Default();
411  }
412  return true;
413 }
static C4SolidMask * Last
Definition: C4SolidMask.h:72
void PutTemporary(C4Rect where)
C4SolidMask * Prev
Definition: C4SolidMask.h:73
static bool CheckConsistency()
void RemoveTemporary(C4Rect where)
static C4SolidMask * First
Definition: C4SolidMask.h:71
C4SolidMask * Next
Definition: C4SolidMask.h:74

References C4LS_MaxRelights, C4SolidMask::CheckConsistency(), C4SolidMask::First, C4SolidMask::Last, C4SolidMask::Next, C4SolidMask::Prev, C4SolidMask::PutTemporary(), and C4SolidMask::RemoveTemporary().

Referenced by Draw(), C4Game::Execute(), and Execute().

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

◆ Draw()

void C4Landscape::Draw ( C4TargetFacet cgo,
class C4FoWRegion pLight = nullptr 
)

Definition at line 369 of file C4Landscape.cpp.

370 {
371  uint32_t clrMod = 0xffffffff;
372  if (p->Modulation)
373  {
374  pDraw->ActivateBlitModulation(p->Modulation);
375  clrMod = p->Modulation;
376  }
377  // blit landscape
378  if (::GraphicsSystem.Show8BitSurface == 1)
379  pDraw->Blit8Fast(p->Surface8.get(), cgo.TargetX, cgo.TargetY, cgo.Surface, cgo.X, cgo.Y, cgo.Wdt, cgo.Hgt);
380  else if (::GraphicsSystem.Show8BitSurface == 2)
381  pDraw->Blit8Fast(p->Surface8Bkg.get(), cgo.TargetX, cgo.TargetY, cgo.Surface, cgo.X, cgo.Y, cgo.Wdt, cgo.Hgt);
382  else if (p->pLandscapeRender)
383  {
384  DoRelights();
385  p->pLandscapeRender->Draw(cgo, pLight, clrMod);
386  }
387  if (p->Modulation) pDraw->DeactivateBlitModulation();
388 }
C4Draw * pDraw
Definition: C4Draw.cpp:42
C4GraphicsSystem GraphicsSystem
Definition: C4Globals.cpp:51
void DeactivateBlitModulation()
Definition: C4Draw.h:189
void Blit8Fast(CSurface8 *sfcSource, int fx, int fy, C4Surface *sfcTarget, int tx, int ty, int wdt, int hgt)
Definition: C4Draw.cpp:251
void ActivateBlitModulation(DWORD dwWithClr)
Definition: C4Draw.h:188
C4Surface * Surface
Definition: C4Facet.h:117
float Hgt
Definition: C4Facet.h:118
float Wdt
Definition: C4Facet.h:118
float Y
Definition: C4Facet.h:118
float X
Definition: C4Facet.h:118
bool DoRelights()
float TargetY
Definition: C4Facet.h:165
float TargetX
Definition: C4Facet.h:165

References C4Draw::ActivateBlitModulation(), C4Draw::Blit8Fast(), C4Draw::DeactivateBlitModulation(), DoRelights(), GraphicsSystem, C4Facet::Hgt, pDraw, C4GraphicsSystem::Show8BitSurface, C4Facet::Surface, C4TargetFacet::TargetX, C4TargetFacet::TargetY, C4Facet::Wdt, C4Facet::X, and C4Facet::Y.

Referenced by C4Viewport::Draw().

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

◆ DrawBox()

bool C4Landscape::DrawBox ( int32_t  iX1,
int32_t  iY1,
int32_t  iX2,
int32_t  iY2,
int32_t  iGrade,
const char *  szMaterial,
const char *  szTexture,
const char *  szBackMaterial,
const char *  szBackTexture 
)

Definition at line 3545 of file C4Landscape.cpp.

3546 {
3547  // get upper-left/lower-right - corners
3548  int32_t iX0 = std::min(iX1, iX2); int32_t iY0 = std::min(iY1, iY2);
3549  iX2 = std::max(iX1, iX2); iY2 = std::max(iY1, iY2); iX1 = iX0; iY1 = iY0;
3550  BYTE byCol, byColBkg;
3551  // Get map color index by material-texture
3552  if (!p->GetMapColorIndex(szMaterial, szTexture, byCol)) return false;
3553  if (!p->GetMapColorIndex(szBackMaterial, szBackTexture, byColBkg)) return false;
3554  // Get material shape size
3555  C4Texture *texture = ::TextureMap.GetTexture(szTexture);
3556  int32_t shape_wdt = 0, shape_hgt = 0;
3557  if (texture && texture->GetMaterialShape())
3558  {
3559  shape_wdt = texture->GetMaterialShape()->GetMaxPolyWidth() / p->MapZoom;
3560  shape_hgt = texture->GetMaterialShape()->GetMaxPolyHeight() / p->MapZoom;
3561  }
3562  // Draw
3563  switch (p->mode)
3564  {
3565  // Dynamic: ignore
3567  break;
3568  // Static: draw to map by material-texture-index, chunk-o-zoom to landscape
3569  case LandscapeMode::Static:
3570  // Draw to map
3571  iX1 /= p->MapZoom; iY1 /= p->MapZoom; iX2 /= p->MapZoom; iY2 /= p->MapZoom;
3572  p->Map->Box(iX1, iY1, iX2, iY2, byCol);
3573  p->MapBkg->Box(iX1, iY1, iX2, iY2, byColBkg);
3574  // Update landscape
3575  p->MapToLandscape(this, *p->Map, *p->MapBkg, iX1 - 1 - shape_wdt, iY1 - 1 - shape_hgt, iX2 - iX1 + 3 + shape_wdt * 2, iY2 - iY1 + 3 + shape_hgt * 2);
3576  SetMapChanged();
3577  break;
3578  // Exact: draw directly to landscape by color & pattern
3579  case LandscapeMode::Exact:
3580  {
3581  C4Rect BoundingBox(iX1, iY1, iX2 - iX1 + 1, iY2 - iY1 + 1);
3582  // Draw to landscape
3583  p->PrepareChange(this, BoundingBox);
3584  p->Surface8->Box(iX1, iY1, iX2, iY2, byCol);
3585  p->Surface8Bkg->Box(iX1, iY1, iX2, iY2, byColBkg);
3586  p->FinishChange(this, BoundingBox);
3587  break;
3588  }
3589  case LandscapeMode::Undefined: assert(false); break;
3590  }
3591  return true;
3592 }
C4TextureMap TextureMap
Definition: C4Texture.cpp:576
void SetMapChanged()
class C4TextureShape * GetMaterialShape() const
Definition: C4Texture.h:40
const char * GetTexture(int32_t iIndex)
Definition: C4Texture.cpp:494
int32_t GetMaxPolyHeight() const
int32_t GetMaxPolyWidth() const

References Dynamic, Exact, C4Texture::GetMaterialShape(), C4TextureShape::GetMaxPolyHeight(), C4TextureShape::GetMaxPolyWidth(), C4TextureMap::GetTexture(), SetMapChanged(), Static, TextureMap, and Undefined.

Here is the call graph for this function:

◆ DrawBrush()

bool C4Landscape::DrawBrush ( int32_t  iX,
int32_t  iY,
int32_t  iGrade,
const char *  szMaterial,
const char *  szTexture,
const char *  szBackMaterial,
const char *  szBackTexture 
)

Definition at line 3415 of file C4Landscape.cpp.

3416 {
3417  BYTE byCol, byColBkg;
3418  // Get map color index by material-texture
3419  if (!p->GetMapColorIndex(szMaterial, szTexture, byCol)) return false;
3420  if (!p->GetMapColorIndex(szBackMaterial, szBackTexture, byColBkg)) return false;
3421  // Get material shape size
3422  C4Texture *texture = ::TextureMap.GetTexture(szTexture);
3423  int32_t shape_wdt = 0, shape_hgt = 0;
3424  if (texture && texture->GetMaterialShape())
3425  {
3426  shape_wdt = texture->GetMaterialShape()->GetMaxPolyWidth() / p->MapZoom;
3427  shape_hgt = texture->GetMaterialShape()->GetMaxPolyHeight() / p->MapZoom;
3428  }
3429  // Draw
3430  switch (p->mode)
3431  {
3432  // Dynamic: ignore
3434  break;
3435  // Static: draw to map by material-texture-index, chunk-o-zoom to landscape
3436  case LandscapeMode::Static:
3437  {
3438  // Draw to map
3439  int32_t iRadius = std::max<int32_t>(2 * iGrade / p->MapZoom, 1);
3440  if (iRadius == 1)
3441  {
3442  p->Map->SetPix(iX / p->MapZoom, iY / p->MapZoom, byCol);
3443  p->MapBkg->SetPix(iX / p->MapZoom, iY / p->MapZoom, byColBkg);
3444  }
3445  else
3446  {
3447  p->Map->Circle(iX / p->MapZoom, iY / p->MapZoom, iRadius, byCol);
3448  p->MapBkg->Circle(iX / p->MapZoom, iY / p->MapZoom, iRadius, byColBkg);
3449  }
3450  // Update landscape
3451  p->MapToLandscape(this, *p->Map, *p->MapBkg, iX / p->MapZoom - iRadius - 1 - shape_wdt, iY / p->MapZoom - iRadius - 1 - shape_hgt, 2 * iRadius + 2 + shape_wdt * 2, 2 * iRadius + 2 + shape_hgt * 2);
3452  SetMapChanged();
3453  }
3454  break;
3455  // Exact: draw directly to landscape by color & pattern
3456  case LandscapeMode::Exact:
3457  {
3458  C4Rect BoundingBox(iX - iGrade - 1, iY - iGrade - 1, iGrade * 2 + 2, iGrade * 2 + 2);
3459  // Draw to landscape
3460  p->PrepareChange(this, BoundingBox);
3461  p->Surface8->Circle(iX, iY, iGrade, byCol);
3462  p->Surface8Bkg->Circle(iX, iY, iGrade, byColBkg);
3463  p->FinishChange(this, BoundingBox);
3464  break;
3465  }
3466  case LandscapeMode::Undefined: assert(false); break;
3467  }
3468  return true;
3469 }

References Dynamic, Exact, C4Texture::GetMaterialShape(), C4TextureShape::GetMaxPolyHeight(), C4TextureShape::GetMaxPolyWidth(), C4TextureMap::GetTexture(), SetMapChanged(), Static, TextureMap, and Undefined.

Here is the call graph for this function:

◆ DrawChunks()

bool C4Landscape::DrawChunks ( int32_t  tx,
int32_t  ty,
int32_t  wdt,
int32_t  hgt,
int32_t  icntx,
int32_t  icnty,
const char *  szMaterial,
const char *  szTexture,
bool  bIFT 
)

Definition at line 3594 of file C4Landscape.cpp.

3595 {
3596  BYTE byColor;
3597  if (!p->GetMapColorIndex(szMaterial, szTexture, byColor)) return false;
3598 
3599  int32_t iMaterial = ::MaterialMap.Get(szMaterial);
3600  if (!MatValid(iMaterial))
3601  return false;
3602 
3604 
3605  C4Rect BoundingBox(tx - 5, ty - 5, wdt + 10, hgt + 10);
3606  p->PrepareChange(this, BoundingBox);
3607 
3608  // assign clipper
3609  p->Surface8->Clip(BoundingBox.x, BoundingBox.y, BoundingBox.x + BoundingBox.Wdt, BoundingBox.y + BoundingBox.Hgt);
3610  p->Surface8Bkg->Clip(BoundingBox.x, BoundingBox.y, BoundingBox.x + BoundingBox.Wdt, BoundingBox.y + BoundingBox.Hgt);
3612 
3613  // draw all chunks
3614  int32_t x, y;
3615  for (x = 0; x < icntx; x++)
3616  for (y = 0; y < icnty; y++)
3617  p->DrawChunk(this, tx + wdt*x / icntx, ty + hgt*y / icnty, wdt / icntx, hgt / icnty, byColor, bIFT ? p->DefaultBkgMat(byColor) : 0, shape, Random(1000));
3618 
3619  // remove clipper
3620  p->Surface8->NoClip();
3621  p->Surface8Bkg->NoClip();
3622 
3623  p->FinishChange(this, BoundingBox);
3624 
3625  // success
3626  return true;
3627 }
C4MaterialCoreShape
Definition: C4Material.h:72
@ C4M_Flat
Definition: C4Material.h:73
uint32_t Random()
Definition: C4Random.cpp:43
bool NoPrimaryClipper()
Definition: C4Draw.cpp:237
C4Scenario C4S
Definition: C4Game.h:74
C4MaterialCoreShape MapChunkType
Definition: C4Material.h:91
int32_t Get(const char *szMaterial)
Definition: C4Material.cpp:365
bool FlatChunkShapes
Definition: C4Scenario.h:188
C4SLandscape Landscape
Definition: C4Scenario.h:236

References C4M_Flat, C4Game::C4S, C4SLandscape::FlatChunkShapes, Game, C4MaterialMap::Get(), C4Rect::Hgt, C4Scenario::Landscape, C4MaterialMap::Map, C4MaterialCore::MapChunkType, MaterialMap, MatValid(), C4Draw::NoPrimaryClipper(), pDraw, Random(), C4Rect::Wdt, CPolyEdge::x, C4Rect::x, CPolyEdge::y, and C4Rect::y.

Here is the call graph for this function:

◆ DrawDefMap()

bool C4Landscape::DrawDefMap ( int32_t  iX,
int32_t  iY,
int32_t  iWdt,
int32_t  iHgt,
const char *  szMapDef,
bool  ignoreSky = false 
)

Definition at line 3989 of file C4Landscape.cpp.

3990 {
3991  // safety
3992  if (!szMapDef || !p->pMapCreator) return false;
3993  // clip to landscape size
3994  if (!ClipRect(iX, iY, iWdt, iHgt)) return false;
3995  // get needed map size
3996  int32_t iMapWdt = (iWdt - 1) / p->MapZoom + 1;
3997  int32_t iMapHgt = (iHgt - 1) / p->MapZoom + 1;
3998  bool fSuccess = false;
3999  // render map
4000  C4MCMap *pMap = p->pMapCreator->GetMap(szMapDef);
4001  if (!pMap) return false;
4002  pMap->SetSize(iMapWdt, iMapHgt);
4003  CSurface8* sfcMap = nullptr;
4004  CSurface8* sfcMapBkg = nullptr;
4005  if (p->pMapCreator->Render(szMapDef, sfcMap, sfcMapBkg))
4006  {
4007  // map to landscape
4008  fSuccess = p->MapToLandscape(this, *sfcMap, *sfcMapBkg, 0, 0, iMapWdt, iMapHgt, iX, iY, ignoreSky);
4009  // cleanup
4010  delete sfcMap;
4011  delete sfcMapBkg;
4012  }
4013  // done
4014  return fSuccess;
4015 }
bool ClipRect(int32_t &rX, int32_t &rY, int32_t &rWdt, int32_t &rHgt) const
void SetSize(int32_t iWdt, int32_t iHgt)

References ClipRect(), and C4MCMap::SetSize().

Here is the call graph for this function:

◆ DrawLine()

bool C4Landscape::DrawLine ( int32_t  iX1,
int32_t  iY1,
int32_t  iX2,
int32_t  iY2,
int32_t  iGrade,
const char *  szMaterial,
const char *  szTexture,
const char *  szBackMaterial,
const char *  szBackTexture 
)

Definition at line 3492 of file C4Landscape.cpp.

3493 {
3494  // Get map color index by material-texture
3495  uint8_t line_color, line_color_bkg;
3496  if (!p->GetMapColorIndex(szMaterial, szTexture, line_color)) return false;
3497  if (!p->GetMapColorIndex(szBackMaterial, szBackTexture, line_color_bkg)) return false;
3498  // Get material shape size
3499  C4Texture *texture = ::TextureMap.GetTexture(szTexture);
3500  int32_t shape_wdt = 0, shape_hgt = 0;
3501  if (texture && texture->GetMaterialShape())
3502  {
3503  shape_wdt = texture->GetMaterialShape()->GetMaxPolyWidth() / p->MapZoom;
3504  shape_hgt = texture->GetMaterialShape()->GetMaxPolyHeight() / p->MapZoom;
3505  }
3506  // Draw
3507  switch (p->mode)
3508  {
3509  // Dynamic: ignore
3511  break;
3512  // Static: draw to map by material-texture-index, chunk-o-zoom to landscape
3513  case LandscapeMode::Static:
3514  {
3515  // Draw to map
3516  int32_t iRadius = std::max<int32_t>(2 * iGrade / p->MapZoom, 1);
3517  iX1 /= p->MapZoom; iY1 /= p->MapZoom; iX2 /= p->MapZoom; iY2 /= p->MapZoom;
3518  ForLine(iX1, iY1, iX2, iY2, [this, line_color, line_color_bkg, iRadius](int32_t x, int32_t y) { return p->DrawLineMap(x, y, iRadius, line_color, line_color_bkg); });
3519  // Update landscape
3520  int iUpX = std::min(iX1, iX2) - iRadius - 1;
3521  int iUpY = std::min(iY1, iY2) - iRadius - 1;
3522  int iUpWdt = Abs(iX2 - iX1) + 2 * iRadius + 2;
3523  int iUpHgt = Abs(iY2 - iY1) + 2 * iRadius + 2;
3524  p->MapToLandscape(this, *p->Map, *p->MapBkg, iUpX - shape_wdt, iUpY - shape_hgt, iUpWdt + shape_wdt * 2, iUpHgt + shape_hgt * 2);
3525  SetMapChanged();
3526  }
3527  break;
3528  // Exact: draw directly to landscape by color & pattern
3529  case LandscapeMode::Exact:
3530  {
3531  // Set texture pattern & get material color
3532  C4Rect BoundingBox(iX1 - iGrade, iY1 - iGrade, iGrade * 2 + 1, iGrade * 2 + 1);
3533  BoundingBox.Add(C4Rect(iX2 - iGrade, iY2 - iGrade, iGrade * 2 + 1, iGrade * 2 + 1));
3534  // Draw to landscape
3535  p->PrepareChange(this, BoundingBox);
3536  ForLine(iX1, iY1, iX2, iY2, [this, line_color, line_color_bkg, iGrade](int32_t x, int32_t y) { return p->DrawLineLandscape(x, y, iGrade, line_color, line_color_bkg); });
3537  p->FinishChange(this, BoundingBox);
3538  break;
3539  }
3540  case LandscapeMode::Undefined: assert(false); break;
3541  }
3542  return true;
3543 }
T Abs(T val)
Definition: Standard.h:42

References Abs(), C4Rect::Add(), Dynamic, Exact, C4Texture::GetMaterialShape(), C4TextureShape::GetMaxPolyHeight(), C4TextureShape::GetMaxPolyWidth(), C4TextureMap::GetTexture(), SetMapChanged(), Static, TextureMap, Undefined, CPolyEdge::x, and CPolyEdge::y.

Here is the call graph for this function:

◆ DrawMap()

bool C4Landscape::DrawMap ( int32_t  iX,
int32_t  iY,
int32_t  iWdt,
int32_t  iHgt,
const char *  szMapDef,
bool  ignoreSky = false 
)

Definition at line 3959 of file C4Landscape.cpp.

3960 {
3961  // safety
3962  if (!szMapDef) return false;
3963  // clip to landscape size
3964  if (!ClipRect(iX, iY, iWdt, iHgt)) return false;
3965  // get needed map size
3966  int32_t iMapWdt = (iWdt - 1) / p->MapZoom + 1;
3967  int32_t iMapHgt = (iHgt - 1) / p->MapZoom + 1;
3968  C4SLandscape FakeLS = Game.C4S.Landscape;
3969  FakeLS.MapWdt.Set(iMapWdt, 0, iMapWdt, iMapWdt);
3970  FakeLS.MapHgt.Set(iMapHgt, 0, iMapHgt, iMapHgt);
3971  // create map creator
3972  C4MapCreatorS2 MapCreator(&FakeLS, &::TextureMap, &::MaterialMap, Game.StartupPlayerCount);
3973  // read file
3974  MapCreator.ReadScript(szMapDef);
3975  // render map
3976  CSurface8* sfcMap = nullptr;
3977  CSurface8* sfcMapBkg = nullptr;
3978  if (!MapCreator.Render(nullptr, sfcMap, sfcMapBkg))
3979  return false;
3980  // map it to the landscape
3981  bool fSuccess = p->MapToLandscape(this, *sfcMap, *sfcMapBkg, 0, 0, iMapWdt, iMapHgt, iX, iY, ignoreSky);
3982  // cleanup
3983  delete sfcMap;
3984  delete sfcMapBkg;
3985  // return whether successful
3986  return fSuccess;
3987 }
int32_t StartupPlayerCount
Definition: C4Game.h:109
C4SVal MapWdt
Definition: C4Scenario.h:178
C4SVal MapHgt
Definition: C4Scenario.h:178
void Set(int32_t std=0, int32_t rnd=0, int32_t min=0, int32_t max=100)
Definition: C4Scenario.cpp:36

References C4Game::C4S, ClipRect(), Game, C4Scenario::Landscape, C4SLandscape::MapHgt, C4SLandscape::MapWdt, MaterialMap, C4MapCreatorS2::ReadScript(), C4MapCreatorS2::Render(), C4SVal::Set(), C4Game::StartupPlayerCount, and TextureMap.

Here is the call graph for this function:

◆ DrawMaterialRect()

void C4Landscape::DrawMaterialRect ( int32_t  mat,
int32_t  tx,
int32_t  ty,
int32_t  wdt,
int32_t  hgt 
)

Definition at line 931 of file C4Landscape.cpp.

932 {
933  int32_t cx, cy;
934  for (cy = ty; cy < ty + hgt; cy++)
935  for (cx = tx; cx < tx + wdt; cx++)
936  if ((MatDensity(mat) >= GetDensity(cx, cy)))
937  SetPix2(cx, cy, Mat2PixColDefault(mat), p->Surface8Bkg->GetPix(cx, cy));
938 }
BYTE Mat2PixColDefault(int32_t mat)
Definition: C4Material.h:235
int32_t MatDensity(int32_t mat)
Definition: C4Material.h:240
int32_t GetDensity(int32_t x, int32_t y) const

References GetDensity(), Mat2PixColDefault(), MatDensity(), and SetPix2().

Here is the call graph for this function:

◆ DrawPolygon()

bool C4Landscape::DrawPolygon ( int *  vtcs,
int  length,
const char *  szMaterial,
const char *  szBackMaterial,
bool  fDrawBridge 
)

Definition at line 3629 of file C4Landscape.cpp.

3630 {
3631  if (length < 6) return false;
3632  if (length % 2 == 1) return false;
3633  // get texture
3634  int32_t iMatTex = ::TextureMap.GetIndexMatTex(szMaterial);
3635  if (!iMatTex) return false;
3636  uint8_t mcol = MatTex2PixCol(iMatTex);
3637  // get background texture
3638  uint8_t mcolBkg = 0;
3639  if (szBackMaterial != nullptr)
3640  {
3641  const int32_t iBackMatTex = ::TextureMap.GetIndexMatTex(szBackMaterial);
3642  if (!iBackMatTex) return false;
3643  mcolBkg = MatTex2PixCol(iBackMatTex);
3644  }
3645  // do bridging?
3646  uint8_t *conversion_map = nullptr;
3647  if (fDrawBridge)
3648  {
3649  conversion_map = p->GetBridgeMatConversion(this, MatTex2PixCol(iMatTex));
3650  mcolBkg = Transparent;
3651  }
3652  // prepare pixel count update
3653  C4Rect BoundingBox = getBoundingBox(vtcs, length);
3654  // draw polygon
3655  p->PrepareChange(this, BoundingBox);
3656  p->ForPolygon(this, vtcs, length / 2, nullptr, nullptr, mcol, mcolBkg, conversion_map);
3657  p->FinishChange(this, BoundingBox);
3658  return true;
3659 }
BYTE MatTex2PixCol(int32_t tex)
Definition: C4Material.h:230
int32_t GetIndexMatTex(const char *szMaterialTexture, const char *szDefaultTexture=nullptr, bool fAddIfNotExist=true, const char *szErrorIfFailed=nullptr)
Definition: C4Texture.cpp:441

References C4TextureMap::GetIndexMatTex(), MatTex2PixCol(), TextureMap, and Transparent.

Referenced by DrawQuad().

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

◆ DrawQuad()

bool C4Landscape::DrawQuad ( int32_t  iX1,
int32_t  iY1,
int32_t  iX2,
int32_t  iY2,
int32_t  iX3,
int32_t  iY3,
int32_t  iX4,
int32_t  iY4,
const char *  szMaterial,
const char *  szBackMaterial,
bool  fDrawBridge 
)

Definition at line 3891 of file C4Landscape.cpp.

3892 {
3893  // set vertices
3894  int32_t vtcs[8];
3895  vtcs[0] = iX1; vtcs[1] = iY1;
3896  vtcs[2] = iX2; vtcs[3] = iY2;
3897  vtcs[4] = iX3; vtcs[5] = iY3;
3898  vtcs[6] = iX4; vtcs[7] = iY4;
3899  return DrawPolygon(vtcs, 8, szMaterial, szBackMaterial, fDrawBridge);
3900 }
bool DrawPolygon(int *vtcs, int length, const char *szMaterial, const char *szBackMaterial, bool fDrawBridge)

References DrawPolygon().

Here is the call graph for this function:

◆ Execute()

void C4Landscape::Execute ( )

Definition at line 204 of file C4Landscape.cpp.

205 {
206  // Landscape scan
207  if (!p->NoScan)
208  p->ExecuteScan(this);
209  // move sky
210  p->Sky.Execute();
211 
212  // Queued Relights -- note that normally we process them before drawing every frame;
213  // this just makes sure relights don't accumulate over a long period of time if no
214  // viewport is open (developer mode).
215  if (!::Game.iTick35)
216  DoRelights();
217 }
int32_t iTick35
Definition: C4Game.h:130

References DoRelights(), Game, and C4Game::iTick35.

Referenced by C4Game::Execute().

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

◆ ExtractMaterial()

int32_t C4Landscape::ExtractMaterial ( int32_t  fx,
int32_t  fy,
bool  distant_first 
)

Definition at line 957 of file C4Landscape.cpp.

958 {
959  int32_t mat = GetMat(fx, fy);
960  if (mat == MNone) return MNone;
961  FindMatTop(mat, fx, fy, distant_first);
962  ClearPix(fx, fy);
963  CheckInstabilityRange(fx, fy);
964  return mat;
965 }
const int32_t MNone
Definition: C4Constants.h:177
void FindMatTop(int32_t mat, int32_t &x, int32_t &y, bool distant_first) const
void CheckInstabilityRange(int32_t tx, int32_t ty)

References CheckInstabilityRange(), ClearPix(), FindMatTop(), GetMat(), and MNone.

Referenced by C4MassMover::Execute(), and C4MaterialMap::mrfPoof().

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

◆ FastSolidCheckNextX()

int32_t C4Landscape::FastSolidCheckNextX ( int32_t  x)
static

Definition at line 3828 of file C4Landscape.cpp.

3829 {
3830  return (x / 17) * 17 + 17;
3831 }

References CPolyEdge::x.

Referenced by C4FoWLightSection::Update().

Here is the caller graph for this function:

◆ FindMatPath()

bool C4Landscape::FindMatPath ( int32_t &  fx,
int32_t &  fy,
int32_t  ydir,
int32_t  mdens,
int32_t  mslide 
) const

Definition at line 3109 of file C4Landscape.cpp.

3110 {
3111  assert(mdens <= C4M_Solid); // mdens normalized in InsertMaterial
3112 
3113  int32_t cslide;
3114  bool fLeft = true, fRight = true;
3115 
3116  // One downwards
3117  if (GetDensity(fx, fy + ydir) < mdens) { fy += ydir; return true; }
3118 
3119  // Find downwards slide path
3120  for (cslide = 1; (cslide <= mslide) && (fLeft || fRight); cslide++)
3121  {
3122  // Check left
3123  if (fLeft)
3124  {
3125  if (GetDensity(fx - cslide, fy) >= mdens) // Left clogged
3126  fLeft = false;
3127  else if (GetDensity(fx - cslide, fy + ydir) < mdens) // Left slide okay
3128  {
3129  fx--; return true;
3130  }
3131  }
3132  // Check right
3133  if (fRight)
3134  {
3135  if (GetDensity(fx + cslide, fy) >= mdens) // Right clogged
3136  fRight = false;
3137  else if (GetDensity(fx + cslide, fy + ydir) < mdens) // Right slide okay
3138  {
3139  fx++; return true;
3140  }
3141  }
3142  }
3143 
3144  return false;
3145 }
const int32_t C4M_Solid
Definition: C4Constants.h:172

References C4M_Solid, and GetDensity().

Referenced by C4MassMover::Execute().

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

◆ FindMatPathPush()

bool C4Landscape::FindMatPathPush ( int32_t &  fx,
int32_t &  fy,
int32_t  mdens,
int32_t  mslide,
bool  liquid 
) const

Definition at line 3188 of file C4Landscape.cpp.

3189 {
3190  // Startpoint must be inside landscape
3191  fx = Clamp<int32_t>(fx, 0, GetWidth() - 1);
3192  fy = Clamp<int32_t>(fy, 0, GetHeight() - 1);
3193  // Range to search, calculate bounds
3194  const int32_t iPushRange = 500;
3195  int32_t left = std::max<int32_t>(0, fx - iPushRange), right = std::min<int32_t>(GetWidth() - 1, fx + iPushRange),
3196  top = std::max<int32_t>(0, fy - iPushRange), bottom = std::min<int32_t>(GetHeight() - 1, fy + iPushRange);
3197  // Direction constants
3198  const int8_t R = 0, D = 1, L = 2, U = 3;
3199  int8_t dir = 0;
3200  int32_t x = fx, y = fy;
3201  // Get startpoint density
3202  int32_t dens = GetDensity(fx, fy);
3203  // Smaller density? We're done.
3204  if (dens < mdens)
3205  return true;
3206  // Right density?
3207  else if (dens == mdens)
3208  {
3209  // Find start point for border search
3210  for (int32_t i = 0; ; i++)
3211  if (x - i - 1 < left || GetDensity(x - i - 1, y) != mdens)
3212  {
3213  x -= i; dir = L; break;
3214  }
3215  else if (y - i - 1 < top || GetDensity(x, y - i - 1) != mdens)
3216  {
3217  y -= i; dir = U; break;
3218  }
3219  else if (x + i + 1 > right || GetDensity(x + i + 1, y) != mdens)
3220  {
3221  x += i; dir = R; break;
3222  }
3223  else if (y + i + 1 > bottom || GetDensity(x, y + i + 1) != mdens)
3224  {
3225  y += i; dir = D; break;
3226  }
3227  }
3228  // Greater density
3229  else
3230  {
3231  // Try to find a way out
3232  int i = 1;
3233  for (; i < iPushRange; i++)
3234  {
3235  if (GetDensity(x - i, y) <= mdens)
3236  {
3237  x -= i; dir = R; break;
3238  }
3239  else if (GetDensity(x, y - i) <= mdens)
3240  {
3241  y -= i; dir = D; break;
3242  }
3243  else if (GetDensity(x + i, y) <= mdens)
3244  {
3245  x += i; dir = L; break;
3246  }
3247  else if (GetDensity(x, y + i) <= mdens)
3248  {
3249  y += i; dir = U; break;
3250  }
3251  }
3252  // Not found?
3253  if (i >= iPushRange) return false;
3254  // Done?
3255  if (GetDensity(x, y) < mdens)
3256  {
3257  fx = x; fy = y;
3258  return true;
3259  }
3260  }
3261  // Save startpoint of search
3262  int32_t sx = x, sy = y, sdir = dir;
3263  // Best point so far
3264  bool fGotBest = false; int32_t bx = 0, by = 0, bdist = 0;
3265  // Start searching
3266  do
3267  {
3268  // We should always be in a material of same density
3269  assert(x >= left && y >= top && x <= right && y <= bottom && GetDensity(x, y) == mdens);
3270  // Calc new position
3271  int nx = x, ny = y;
3272  switch (dir)
3273  {
3274  case R: nx++; break;
3275  case D: ny++; break;
3276  case L: nx--; break;
3277  case U: ny--; break;
3278  default: assert(false);
3279  }
3280  // In bounds?
3281  bool fInBounds = (nx >= left && ny >= top && nx <= right && ny <= bottom);
3282  // Get density. Not this performs an SideOpen-check if outside landscape bounds.
3283  int32_t dens = GetDensity(nx, ny);
3284  // Flow possible?
3285  if (dens < mdens)
3286  {
3287  // Calculate "distance".
3288  int32_t dist = Abs(nx - fx) + mslide * (liquid ? fy - ny : Abs(fy - ny));
3289  // New best point?
3290  if (!fGotBest || dist < bdist)
3291  {
3292  // Save it
3293  bx = nx; by = ny; bdist = dist; fGotBest = true;
3294  // Adjust borders: We can obviously safely ignore anything at greater distance
3295  top = std::max<int32_t>(top, fy - dist / mslide - 1);
3296  if (!liquid)
3297  {
3298  bottom = std::min<int32_t>(bottom, fy + dist / mslide + 1);
3299  left = std::max<int32_t>(left, fx - dist - 1);
3300  right = std::min<int32_t>(right, fx + dist + 1);
3301  }
3302  // Set new startpoint
3303  sx = x; sy = y; sdir = dir;
3304  }
3305  }
3306  // Step?
3307  if (fInBounds && dens == mdens)
3308  {
3309  // New point
3310  x = nx; y = ny;
3311  // Turn left
3312  (dir += 3) %= 4;
3313  }
3314  // Otherwise: Turn right
3315  else
3316  {
3317  ++dir;
3318  dir %= 4;
3319  }
3320  } while (x != sx || y != sy || dir != sdir);
3321  // Nothing found?
3322  if (!fGotBest) return false;
3323  // Return it
3324  fx = bx; fy = by;
3325  return true;
3326 }

References Abs(), C4ScriptGuiWindowPropertyName::bottom, GetDensity(), GetHeight(), GetWidth(), C4ScriptGuiWindowPropertyName::left, C4ScriptGuiWindowPropertyName::right, C4ScriptGuiWindowPropertyName::top, CPolyEdge::x, and CPolyEdge::y.

Referenced by InsertMaterial().

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

◆ FindMatSlide()

bool C4Landscape::FindMatSlide ( int32_t &  fx,
int32_t &  fy,
int32_t  ydir,
int32_t  mdens,
int32_t  mslide 
) const

Definition at line 3148 of file C4Landscape.cpp.

3149 {
3150  assert(mdens <= C4M_Solid); // mdens normalized in InsertMaterial and mrfInsertCheck
3151  int32_t cslide;
3152  bool fLeft = true, fRight = true;
3153 
3154  // One downwards
3155  if (GetDensity(fx, fy + ydir) < mdens) { fy += ydir; return true; }
3156 
3157  // Find downwards slide path
3158  for (cslide = 1; (cslide <= mslide) && (fLeft || fRight); cslide++)
3159  {
3160  // Check left
3161  if (fLeft)
3162  {
3163  if (GetDensity(fx - cslide, fy) >= mdens && GetDensity(fx - cslide, fy + ydir) >= mdens) // Left clogged
3164  fLeft = false;
3165  else if (GetDensity(fx - cslide, fy + ydir) < mdens) // Left slide okay
3166  {
3167  fx -= cslide; fy += ydir; return true;
3168  }
3169  }
3170  // Check right
3171  if (fRight)
3172  {
3173  if (GetDensity(fx + cslide, fy) >= mdens && GetDensity(fx + cslide, fy + ydir) >= mdens) // Right clogged
3174  fRight = false;
3175  else if (GetDensity(fx + cslide, fy + ydir) < mdens) // Right slide okay
3176  {
3177  fx += cslide; fy += ydir; return true;
3178  }
3179  }
3180  }
3181 
3182  return false;
3183 }

References C4M_Solid, and GetDensity().

Referenced by InsertMaterial().

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

◆ FindMatTop()

void C4Landscape::FindMatTop ( int32_t  mat,
int32_t &  x,
int32_t &  y,
bool  distant_first 
) const

Definition at line 3338 of file C4Landscape.cpp.

3339 {
3340  int32_t mslide, cslide, tslide, distant_x = 0;
3341  bool fLeft, fRight;
3342 
3343  if (!MatValid(mat)) return;
3344  mslide = ::MaterialMap.Map[mat].MaxSlide;
3345 
3346  do
3347  {
3348  // Catch most common case: Walk upwards until material changes
3349  while (GetMat(x, y - 1) == mat) --y;
3350 
3351  // Find upwards slide
3352  fLeft = true; fRight = true; tslide = 0; distant_x = x;
3353  for (cslide = 1; (cslide <= mslide) && (fLeft || fRight); cslide++)
3354  {
3355  // Left
3356  if (fLeft)
3357  {
3358  if (GetMat(x - cslide, y) != mat) fLeft = false;
3359  else
3360  {
3361  distant_x = x - cslide;
3362  if (GetMat(distant_x, y - 1) == mat) { tslide = -cslide; break; }
3363  }
3364  }
3365  // Right
3366  if (fRight)
3367  {
3368  if (GetMat(x + cslide, y) != mat) fRight = false;
3369  else
3370  {
3371  distant_x = x + cslide;
3372  if (GetMat(distant_x, y - 1) == mat) { tslide = +cslide; break; }
3373  }
3374  }
3375  }
3376 
3377  // Slide
3378  if (tslide) { x += tslide; y--; }
3379 
3380  } while (tslide);
3381 
3382  // return top pixel max slide away from center if desired
3383  if (distant_first) x = distant_x;
3384 
3385 }
int32_t MaxSlide
Definition: C4Material.h:104

References GetMat(), C4MaterialMap::Map, MaterialMap, MatValid(), C4MaterialCore::MaxSlide, CPolyEdge::x, and CPolyEdge::y.

Referenced by ExtractMaterial().

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

◆ GetBackDensity()

int32_t C4Landscape::GetBackDensity ( int32_t  x,
int32_t  y 
) const

Definition at line 3803 of file C4Landscape.cpp.

3804 {
3805  return p->Pix2Dens[GetBackPix(x, y)];
3806 }
BYTE GetBackPix(int32_t x, int32_t y) const

References GetBackPix(), CPolyEdge::x, and CPolyEdge::y.

Here is the call graph for this function:

◆ GetBackMapIndex()

BYTE C4Landscape::GetBackMapIndex ( int32_t  iX,
int32_t  iY 
) const

Definition at line 3908 of file C4Landscape.cpp.

3909 {
3910  if (!p->MapBkg) return 0;
3911  return p->MapBkg->GetPix(iX, iY);
3912 }

Referenced by C4EditCursor::ApplyToolPicker().

Here is the caller graph for this function:

◆ GetBackMat()

int32_t C4Landscape::GetBackMat ( int32_t  x,
int32_t  y 
) const

Definition at line 3798 of file C4Landscape.cpp.

3799 {
3800  return p->Pix2Mat[GetBackPix(x, y)];
3801 }

References GetBackPix(), CPolyEdge::x, and CPolyEdge::y.

Referenced by C4EditCursor::UpdateStatusBar().

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

◆ GetBackPix()

BYTE C4Landscape::GetBackPix ( int32_t  x,
int32_t  y 
) const

Definition at line 3760 of file C4Landscape.cpp.

3761 {
3762  // Border checks
3763  if (x < 0)
3764  {
3765  return p->DefaultBkgMat(p->LeftColPix[Clamp(y, 0, GetHeight()-1)]);
3766  }
3767  if (static_cast<uint32_t>(x) >= static_cast<uint32_t>(GetWidth()))
3768  {
3769  return p->DefaultBkgMat(p->RightColPix[Clamp(y, 0, GetHeight()-1)]);
3770  }
3771  if (y < 0)
3772  {
3773  return p->DefaultBkgMat(p->TopRowPix[x]);
3774  }
3775  if (static_cast<uint32_t>(y) >= static_cast<uint32_t>(GetHeight()))
3776  {
3777  return p->DefaultBkgMat(p->BottomRowPix[x]);
3778  }
3779 
3780  return p->Surface8Bkg->_GetPix(x, y);
3781 }
T Clamp(T bval, T lbound, T rbound)
Definition: Standard.h:44

References Clamp(), GetHeight(), GetWidth(), CPolyEdge::x, and CPolyEdge::y.

Referenced by C4EditCursor::ApplyToolPicker(), FindTunnelHeight(), GetBackDensity(), GetBackMat(), GetBackPlacement(), GetLight(), C4Weather::GetWind(), and RaiseTerrain().

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

◆ GetBackPlacement()

int32_t C4Landscape::GetBackPlacement ( int32_t  x,
int32_t  y 
) const

Definition at line 3808 of file C4Landscape.cpp.

3809 {
3810  return p->Pix2Place[GetBackPix(x, y)];
3811 }

References GetBackPix(), CPolyEdge::x, and CPolyEdge::y.

Here is the call graph for this function:

◆ GetDensity()

int32_t C4Landscape::GetDensity ( int32_t  x,
int32_t  y 
) const

Definition at line 3742 of file C4Landscape.cpp.

3743 {
3744  return p->Pix2Dens[GetPix(x, y)];
3745 }
BYTE GetPix(int32_t x, int32_t y) const

References GetPix(), CPolyEdge::x, and CPolyEdge::y.

Referenced by DrawMaterialRect(), FindMatPath(), FindMatPathPush(), FindMatSlide(), GBackDensity(), InsertMaterial(), InsertMaterialOutsideLandscape(), and mrfInsertCheck().

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

◆ GetEffectiveMatCount()

int32_t C4Landscape::GetEffectiveMatCount ( int  material) const

Definition at line 4208 of file C4Landscape.cpp.

4209 {
4210  assert(material >= 0 && (unsigned) material < p->EffectiveMatCount.size());
4211  return p->EffectiveMatCount[material];
4212 }

◆ GetFoW()

C4FoW * C4Landscape::GetFoW ( )

Definition at line 4197 of file C4Landscape.cpp.

4198 {
4199  return p->pFoW.get();
4200 }

Referenced by C4Viewport::EnableFoW(), C4Object::StatusDeactivate(), and C4Object::UpdateLight().

Here is the caller graph for this function:

◆ GetGravity()

C4Real C4Landscape::GetGravity ( ) const

Definition at line 3681 of file C4Landscape.cpp.

3682 {
3683  return p->Gravity;
3684 }

◆ GetHeight()

◆ GetLight()

bool C4Landscape::GetLight ( int32_t  x,
int32_t  y 
)

Definition at line 3813 of file C4Landscape.cpp.

3814 {
3815  return GetBackPix(x, y) == 0 || p->Pix2Light[GetPix(x, y)];
3816 }

References GetBackPix(), GetPix(), CPolyEdge::x, and CPolyEdge::y.

Here is the call graph for this function:

◆ GetMapIndex()

BYTE C4Landscape::GetMapIndex ( int32_t  iX,
int32_t  iY 
) const

Definition at line 3902 of file C4Landscape.cpp.

3903 {
3904  if (!p->Map) return 0;
3905  return p->Map->GetPix(iX, iY);
3906 }

Referenced by C4EditCursor::ApplyToolPicker().

Here is the caller graph for this function:

◆ GetMapZoom()

int32_t C4Landscape::GetMapZoom ( ) const

Definition at line 3676 of file C4Landscape.cpp.

3677 {
3678  return p->MapZoom;
3679 }

Referenced by C4EditCursor::ApplyToolPicker(), and C4Player::Execute().

Here is the caller graph for this function:

◆ GetMat()

int32_t C4Landscape::GetMat ( int32_t  x,
int32_t  y 
) const

Definition at line 3737 of file C4Landscape.cpp.

3738 {
3739  return p->Pix2Mat[GetPix(x, y)];
3740 }

References GetPix(), CPolyEdge::x, and CPolyEdge::y.

Referenced by C4Landscape::P::BlastFreePix(), CheckInstability(), C4Landscape::P::DigFreePix(), C4Landscape::P::DigFreePixNoInstability(), ExtractMaterial(), FindMatTop(), GBackMat(), Incinerate(), InsertDeadMaterial(), InsertMaterial(), C4Landscape::P::ShakeFreePix(), and C4EditCursor::UpdateStatusBar().

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

◆ GetMatCount()

int32_t C4Landscape::GetMatCount ( int  material) const

Definition at line 4202 of file C4Landscape.cpp.

4203 {
4204  assert(material >= 0 && (unsigned) material < p->MatCount.size());
4205  return p->MatCount[material];
4206 }

Referenced by C4SolidMask::CheckConsistency().

Here is the caller graph for this function:

◆ GetMatHeight()

int32_t C4Landscape::GetMatHeight ( int32_t  x,
int32_t  y,
int32_t  iYDir,
int32_t  iMat,
int32_t  iMax 
) const

Definition at line 2461 of file C4Landscape.cpp.

2462 {
2463  if (iYDir > 0)
2464  {
2465  iMax = std::min<int32_t>(iMax, GetHeight() - y);
2466  for (int32_t i = 0; i < iMax; i++)
2467  if (_GetMat(x, y + i) != iMat)
2468  return i;
2469  }
2470  else
2471  {
2472  iMax = std::min<int32_t>(iMax, y + 1);
2473  for (int32_t i = 0; i < iMax; i++)
2474  if (_GetMat(x, y - i) != iMat)
2475  return i;
2476  }
2477  return iMax;
2478 }
int32_t _GetMat(int32_t x, int32_t y) const

References _GetMat(), GetHeight(), CPolyEdge::x, and CPolyEdge::y.

Referenced by _SetPix2(), and C4Landscape::P::UpdateMatCnt().

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

◆ GetMode()

LandscapeMode C4Landscape::GetMode ( ) const

Definition at line 3395 of file C4Landscape.cpp.

3396 {
3397  return p->mode;
3398 }

Referenced by C4EditCursor::ApplyToolBrush(), C4EditCursor::ApplyToolFill(), C4EditCursor::ApplyToolLine(), C4EditCursor::ApplyToolPicker(), C4EditCursor::ApplyToolRect(), C4ToolsDlg::AssertValidBackTexture(), C4ToolsDlg::AssertValidTexture(), C4Console::SaveScenario(), C4ToolsDlg::SetBackMaterial(), C4ToolsDlg::SetLandscapeMode(), and C4ToolsDlg::SetMaterial().

Here is the caller graph for this function:

◆ GetModulation()

DWORD C4Landscape::GetModulation ( ) const

Definition at line 4025 of file C4Landscape.cpp.

4025 { return p->Modulation; }

◆ GetPal()

CStdPalette * C4Landscape::GetPal ( ) const

Definition at line 3661 of file C4Landscape.cpp.

3662 {
3663  return p->Surface8 ? p->Surface8->pPal : nullptr;
3664 }

Referenced by C4PXSSystem::Draw().

Here is the caller graph for this function:

◆ GetPix()

BYTE C4Landscape::GetPix ( int32_t  x,
int32_t  y 
) const

Definition at line 3699 of file C4Landscape.cpp.

3700 {
3701  extern BYTE MCVehic;
3702  // Border checks
3703  if (x < 0)
3704  {
3705  return p->LeftColPix[Clamp(y, 0, GetHeight()-1)];
3706  }
3707  if (static_cast<uint32_t>(x) >= static_cast<uint32_t>(p->Width))
3708  {
3709  return p->RightColPix[Clamp(y, 0, GetHeight()-1)];
3710  }
3711  if (y < 0)
3712  {
3713  return p->TopRowPix[x];
3714  }
3715  if (static_cast<uint32_t>(y) >= static_cast<uint32_t>(p->Height))
3716  {
3717  return p->BottomRowPix[x];
3718  }
3719  return p->Surface8->_GetPix(x, y);
3720 }
BYTE MCVehic
Definition: C4Material.cpp:37

References Clamp(), GetHeight(), MCVehic, CPolyEdge::x, and CPolyEdge::y.

Referenced by GetDensity(), GetLight(), GetMat(), GetPlacement(), PathFreeIgnoreVehiclePix(), C4SolidMask::Put(), C4SolidMask::PutTemporary(), RaiseTerrain(), C4SolidMask::RemoveTemporary(), and C4SolidMask::Repair().

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

◆ GetPixDensity()

int32_t C4Landscape::GetPixDensity ( BYTE  byPix) const

Definition at line 3835 of file C4Landscape.cpp.

3835 { return p->Pix2Dens[byPix]; }

Referenced by C4Landscape::P::GetBridgeMatConversion().

Here is the caller graph for this function:

◆ GetPixMat()

int32_t C4Landscape::GetPixMat ( BYTE  byPix) const

Definition at line 3833 of file C4Landscape.cpp.

3833 { return p->Pix2Mat[byPix]; }

Referenced by C4Landscape::P::GetBridgeMatConversion(), and PathFreeIgnoreVehiclePix().

Here is the caller graph for this function:

◆ GetPlacement()

int32_t C4Landscape::GetPlacement ( int32_t  x,
int32_t  y 
) const

Definition at line 3747 of file C4Landscape.cpp.

3748 {
3749  return p->Pix2Place[GetPix(x, y)];
3750 }

References GetPix(), CPolyEdge::x, and CPolyEdge::y.

Here is the call graph for this function:

◆ GetSky()

C4Sky & C4Landscape::GetSky ( )

Definition at line 4187 of file C4Landscape.cpp.

4188 {
4189  return p->Sky;
4190 }

Referenced by C4Game::CompileFunc(), C4GraphicsSystem::DoSaveScreenshot(), and C4Viewport::Draw().

Here is the caller graph for this function:

◆ GetWidth()

◆ HandleTexMapUpdate()

void C4Landscape::HandleTexMapUpdate ( )

Definition at line 4218 of file C4Landscape.cpp.

4219 {
4220  // Pixel maps must be update
4221  UpdatePixMaps();
4222  // Update landscape palette
4223  p->Mat2Pal();
4224 }
void UpdatePixMaps()

References UpdatePixMaps().

Referenced by C4TextureMap::AddEntry().

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

◆ HasFoW()

bool C4Landscape::HasFoW ( ) const

Definition at line 4192 of file C4Landscape.cpp.

4193 {
4194  return p->pFoW != nullptr;
4195 }

Referenced by C4Viewport::EnableFoW(), C4Object::StatusDeactivate(), and C4Object::UpdateLight().

Here is the caller graph for this function:

◆ HasMap()

bool C4Landscape::HasMap ( ) const

Definition at line 1688 of file C4Landscape.cpp.

1689 {
1690  return p->Map != nullptr && p->MapBkg != nullptr;
1691 }

◆ Incinerate()

bool C4Landscape::Incinerate ( int32_t  x,
int32_t  y,
int32_t  cause_player 
)

Definition at line 1084 of file C4Landscape.cpp.

1085 {
1086  int32_t mat = GetMat(x, y);
1087  if (MatValid(mat))
1088  if (::MaterialMap.Map[mat].Inflammable)
1089  {
1090  C4AulParSet pars(C4VInt(x), C4VInt(y), C4VInt(cause_player));
1092  }
1093  return false;
1094 }
C4AulScriptEngine ScriptEngine
Definition: C4Globals.cpp:43
@ P_InflameLandscape
C4Value C4VInt(int32_t i)
Definition: C4Value.h:239
C4PropListStatic * GetPropList()
Definition: C4Aul.h:151
int32_t Inflammable
Definition: C4Material.h:106
C4Value Call(C4PropertyName k, C4AulParSet *pPars=nullptr, bool fPassErrors=false)
Definition: C4PropList.h:114

References C4VInt(), C4PropList::Call(), GetMat(), C4AulScriptEngine::GetPropList(), C4MaterialCore::Inflammable, C4MaterialMap::Map, MaterialMap, MatValid(), P_InflameLandscape, and ScriptEngine.

Referenced by C4MaterialMap::mrfIncinerate().

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

◆ Init()

bool C4Landscape::Init ( C4Group hGroup,
bool  fOverloadCurrent,
bool  fLoadSky,
bool &  rfLoaded,
bool  fSavegame 
)

Definition at line 1426 of file C4Landscape.cpp.

1427 {
1428  // set map seed, if not pre-assigned
1429  if (!p->MapSeed) p->MapSeed = Random(3133700);
1430 
1431  // increase max map size, since developers might set a greater one here
1432  Game.C4S.Landscape.MapWdt.Max = 10000;
1433  Game.C4S.Landscape.MapHgt.Max = 10000;
1434 
1435  // map and landscape must be initialized with fixed random, so runtime joining clients may recreate it
1436  // with same seed
1437  // after map/landscape creation, the seed must be fixed again, so there's no difference between clients creating
1438  // and not creating the map
1439  // this, however, would cause syncloss to DebugRecs
1441 
1443 
1444  // map is like it's loaded for regular gamestart
1445  // but it's changed and would have to be saved if a new section is loaded
1446  p->fMapChanged = fOverloadCurrent;
1447 
1448  // don't change landscape mode in runtime joins
1449  bool fLandscapeModeSet = (p->mode != LandscapeMode::Undefined);
1450 
1451  // Make pixel maps
1452  // Pixel maps only depend on loaded materials and textures
1453  // They might be accessed in map scripts, so they should be ready before map creation
1454  UpdatePixMaps();
1455 
1456  Game.SetInitProgress(60);
1457  // create map if necessary
1459  {
1460  std::unique_ptr<CSurface8> sfcMap, sfcMapBkg;
1461 
1462  // Static map from scenario: Old-style Map.bmp with highest bit IFT
1463  if ((sfcMap = GroupReadSurface8(hGroup, C4CFN_Map)))
1464  {
1465  if (!fLandscapeModeSet) p->mode = LandscapeMode::Static;
1466  sfcMapBkg = p->CreateDefaultBkgSurface(*sfcMap, true);
1467  if (!sfcMapBkg) return false;
1468  }
1469 
1470  // Static map from scenario: New-style MapFg.bmp and MapBg.bmp with
1471  // full 255 mat-tex combinations. Background map is optional, if not
1472  // given default will be created with tunnel background for all
1473  // semisolid pixels.
1474  if (!sfcMap)
1475  {
1476  if ((sfcMap = GroupReadSurface8(hGroup, C4CFN_MapFg)))
1477  {
1478  if (!fLandscapeModeSet) p->mode = LandscapeMode::Static;
1479  sfcMapBkg = GroupReadSurface8(hGroup, C4CFN_MapBg);
1480  if (!sfcMapBkg) sfcMapBkg = p->CreateDefaultBkgSurface(*sfcMap, false);
1481  if (!sfcMapBkg) return false;
1482  }
1483  }
1484 
1485  // dynamic map from Landscape.txt
1486  CSurface8 *rendered_map = nullptr, *rendered_bkg = nullptr;
1487  if (!sfcMap)
1488  {
1489  if (p->CreateMapS2(hGroup, rendered_map, rendered_bkg))
1490  {
1491  sfcMap.reset(rendered_map);
1492  sfcMapBkg.reset(rendered_bkg);
1493  if (!fLandscapeModeSet) p->mode = LandscapeMode::Dynamic;
1494  }
1495  }
1496 
1497  // script may create or edit map
1499  {
1500  if (!fLandscapeModeSet) p->mode = LandscapeMode::Dynamic;
1501  }
1502 
1503  // Dynamic map by scenario
1504  if (!sfcMap && !fOverloadCurrent)
1505  {
1506  if (p->CreateMap(rendered_map, rendered_bkg))
1507  {
1508  sfcMap.reset(rendered_map);
1509  sfcMapBkg.reset(rendered_bkg);
1510  // Although this is a dynamic map, it's probably just the empty default map.
1511  // Set the mode to static so people can start drawing directly in the editor.
1512  if (!fLandscapeModeSet) p->mode = LandscapeMode::Static;
1513  }
1514  }
1515 
1516  // No map failure
1517  if (!sfcMap)
1518  {
1519  // no problem if only overloading
1520  if (!fOverloadCurrent) return false;
1521  if (fLoadSky) if (!p->Sky.Init(fSavegame)) return false;
1522  return true;
1523  }
1524 
1525  assert(sfcMapBkg != nullptr);
1526 
1527  if (Config.General.DebugRec)
1528  {
1529  AddDbgRec(RCT_Block, "|---MAP---|", 12);
1530  AddDbgRec(RCT_Map, sfcMap->Bits, sfcMap->Pitch*sfcMap->Hgt);
1531  }
1532 
1533  // Store map size and calculate map zoom
1534  int iWdt, iHgt;
1535  sfcMap->GetSurfaceSize(iWdt, iHgt);
1536  p->MapWidth = iWdt; p->MapHeight = iHgt;
1537  p->MapZoom = Game.C4S.Landscape.MapZoom.Evaluate();
1538 
1539  // Calculate landscape size
1540  p->Width = p->MapZoom * p->MapWidth;
1541  p->Height = p->MapZoom * p->MapHeight;
1542  p->Width = std::max<int32_t>(p->Width, 100);
1543  p->Height = std::max<int32_t>(p->Height, 100);
1544 
1545  // if overloading, clear current landscape (and sections, etc.)
1546  // must clear, of course, before new sky is eventually read
1547  if (fOverloadCurrent) Clear(!Game.C4S.Landscape.KeepMapCreator, fLoadSky, false);
1548 
1549  // assign new map
1550  assert(p->Map == nullptr);
1551  assert(p->MapBkg == nullptr);
1552  p->Map = std::move(sfcMap);
1553  p->MapBkg = std::move(sfcMapBkg);
1554 
1555  // Sky (might need to know landscape height)
1556  if (fLoadSky)
1557  {
1558  Game.SetInitProgress(70);
1559  if (!p->Sky.Init(fSavegame)) return false;
1560  }
1561  }
1562 
1563  // Exact landscape from scenario (no map or exact recreation)
1564  else /* if (Game.C4S.Landscape.ExactLandscape) */
1565  {
1566  C4DebugRecOff DBGRECOFF;
1567  // if overloading, clear current
1568  if (fOverloadCurrent) Clear(!Game.C4S.Landscape.KeepMapCreator, fLoadSky, false);
1569  // load it
1570  if (!fLandscapeModeSet) p->mode = LandscapeMode::Exact;
1571  rfLoaded = true;
1572  if (!Load(hGroup, fLoadSky, fSavegame)) return false;
1573  }
1574 
1575  // progress
1576  Game.SetInitProgress(75);
1577 
1578  // copy noscan-var
1579  p->NoScan = Game.C4S.Landscape.NoScan != 0;
1580 
1581  // Scan settings
1582  p->ScanSpeed = Clamp(GetWidth() / 500, 2, 15);
1583 
1584  // Create pixel count array before any SetPix operations may take place
1585  // Proper pixel counts will be done later, but needs to have the arrays redy to avoid dead pointer access.
1586  // We will use 15x17 blocks so the pixel count can't get over 255.
1587  int32_t PixCntWidth = (GetWidth() + 16) / 17;
1588  p->PixCntPitch = (GetHeight() + 14) / 15;
1589  p->PixCnt.resize(PixCntWidth * p->PixCntPitch);
1590 
1591  // map to big surface and sectionize it
1592  // (not for shaders though - they require continous textures)
1594  {
1595  assert(p->Surface8 == nullptr);
1596  assert(p->Surface8Bkg == nullptr);
1597 
1598  // Create landscape surfaces
1599  {
1600  auto sf8 = std::make_unique<CSurface8>();
1601  auto sfb8 = std::make_unique<CSurface8>();
1602  if (!sf8->Create(GetWidth(), GetHeight()) || !sfb8->Create(GetWidth(), GetHeight()))
1603  return false;
1604  p->Surface8 = std::move(sf8);
1605  p->Surface8Bkg = std::move(sfb8);
1606  if (!p->Mat2Pal())
1607  return false;
1608  }
1609 
1610  // Map to landscape
1611  // Landscape render disabled during initial landscape zoom (will be updated later)
1612  std::unique_ptr<C4LandscapeRender> lsrender_backup;
1613  lsrender_backup.swap(p->pLandscapeRender);
1614  bool map2landscape_success = MapToLandscape();
1615  lsrender_backup.swap(p->pLandscapeRender);
1616  if (!map2landscape_success) return false;
1617  }
1618 
1619  // Init out-of-landscape pixels for bottom
1620  p->InitBorderPix();
1621 
1622  Game.SetInitProgress(80);
1623 
1624  if (Config.General.DebugRec)
1625  {
1626  AddDbgRec(RCT_Block, "|---LANDSCAPE---|", 18);
1627  AddDbgRec(RCT_Map, p->Surface8->Bits, p->Surface8->Pitch * p->Surface8->Hgt);
1628 
1629  AddDbgRec(RCT_Block, "|---LANDSCAPE BKG---|", 22);
1630  AddDbgRec(RCT_Map, p->Surface8Bkg->Bits, p->Surface8Bkg->Pitch * p->Surface8Bkg->Hgt);
1631  }
1632 
1633  // Create FoW
1634  assert(p->pFoW == nullptr);
1635  if (Game.C4S.Game.FoWEnabled)
1636  p->pFoW = std::make_unique<C4FoW>();
1637 
1638  // Create renderer
1639 #ifndef USE_CONSOLE
1640  if (!p->pLandscapeRender)
1641  p->pLandscapeRender = std::make_unique<C4LandscapeRenderGL>();
1642 #endif
1643 
1644  if (p->pLandscapeRender)
1645  {
1646  // Initialize renderer
1647  if (fOverloadCurrent)
1648  {
1649  if (!p->pLandscapeRender->ReInit(GetWidth(), GetHeight()))
1650  return false;
1651  }
1652  else
1653  {
1654  if (!p->pLandscapeRender->Init(GetWidth(), GetHeight(), &::TextureMap, &::GraphicsResource.Files))
1655  return false;
1656  }
1657  }
1658 
1659  // Save initial landscape
1660  if (!SaveInitial())
1661  return false;
1662 
1663  // Load diff, if existant
1664  ApplyDiff(hGroup);
1665 
1666  // Pixel count tracking from landscape zoom is incomplete, so recalculate it.
1667  p->UpdatePixCnt(this, C4Rect(0, 0, GetWidth(), GetHeight()));
1668  p->ClearMatCount();
1669  p->UpdateMatCnt(this, C4Rect(0, 0, GetWidth(), GetHeight()), true);
1670 
1671  // Create initial landscape render data (after applying diff so landscape is complete)
1672  if (p->pLandscapeRender) p->pLandscapeRender->Update(C4Rect(0, 0, GetWidth(), GetHeight()), this);
1673  Game.SetInitProgress(87);
1674 
1675  // after map/landscape creation, the seed must be fixed again, so there's no difference between clients creating
1676  // and not creating the map
1678 
1679  // Create ambient light map after landscape creation
1680  if (p->pFoW) p->pFoW->Ambient.CreateFromLandscape(*this, 10., 50., 0.25);
1681  Game.SetInitProgress(84);
1682 
1683  // Success
1684  rfLoaded = true;
1685  return true;
1686 }
#define C4CFN_MapFg
Definition: C4Components.h:58
#define C4CFN_MapBg
Definition: C4Components.h:59
#define C4CFN_Map
Definition: C4Components.h:57
C4GraphicsResource GraphicsResource
C4MapScriptHost MapScript
@ RCT_Block
Definition: C4Record.h:55
@ RCT_Map
Definition: C4Record.h:70
void FixRandom(uint64_t seed)
Definition: C4Game.cpp:3801
void SetInitProgress(float to_progress)
Definition: C4Game.cpp:4207
int32_t RandomSeed
Definition: C4Game.h:135
bool SaveInitial()
bool MapToLandscape()
bool ApplyDiff(C4Group &hGroup)
bool Load(C4Group &hGroup, bool fLoadSky, bool fSavegame)
bool InitializeMap(C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, uint32_t iPlayerCount, std::unique_ptr< CSurface8 > *pmap_fg_surface, std::unique_ptr< CSurface8 > *pmap_bg_surface)
bool FoWEnabled
Definition: C4Scenario.h:125
bool KeepMapCreator
Definition: C4Scenario.h:185
C4SVal MapZoom
Definition: C4Scenario.h:178
bool ExactLandscape
Definition: C4Scenario.h:165
int32_t Evaluate()
Definition: C4Scenario.cpp:50
int32_t Max
Definition: C4Scenario.h:31
C4SGame Game
Definition: C4Scenario.h:234

References C4Game::C4S, C4SLandscape::ExactLandscape, C4Game::FixRandom(), Game, C4Scenario::Landscape, C4SLandscape::MapHgt, C4SLandscape::MapWdt, C4SVal::Max, Random(), C4Game::RandomSeed, C4Game::SetInitProgress(), Undefined, and UpdatePixMaps().

Here is the call graph for this function:

◆ InsertDeadMaterial()

bool C4Landscape::InsertDeadMaterial ( int32_t  mat,
int32_t  tx,
int32_t  ty 
)

Definition at line 1047 of file C4Landscape.cpp.

1048 {
1049  // Check bounds
1050  if (tx < 0 || ty < 0 || tx >= GetWidth() || ty >= GetHeight())
1051  return InsertMaterialOutsideLandscape(tx, ty, std::min(MatDensity(mat), C4M_Solid));
1052 
1053  // Save back original material so we can insert it later
1054  int omat = 0;
1056  omat = GetMat(tx, ty);
1057 
1058  // Check surroundings for inspiration for texture to use
1059  int n = 0; int pix = -1;
1060  if (tx > 0 && _GetMat(tx - 1, ty) == mat)
1061  if (!Random(++n)) pix = _GetPix(tx - 1, ty);
1062  if (ty > 0 && _GetMat(tx, ty - 1) == mat)
1063  if (!Random(++n)) pix = _GetPix(tx, ty - 1);
1064  if (tx + 1 < GetWidth() && _GetMat(tx + 1, ty) == mat)
1065  if (!Random(++n)) pix = _GetPix(tx + 1, ty);
1066  if (ty + 1 < GetHeight() && _GetMat(tx, ty + 1) == mat)
1067  if (!Random(++n)) pix = _GetPix(tx, ty + 1);
1068  if (pix < 0)
1069  pix = Mat2PixColDefault(mat);
1070 
1071  // Insert dead material
1072  SetPix2(tx, ty, pix, Transparent);
1073 
1074  // Search a position for the old material pixel
1076  {
1077  int32_t tyo = ty - 1;
1078  InsertMaterial(omat, &tx, &tyo);
1079  }
1080 
1081  return true;
1082 }
bool InsertMaterialOutsideLandscape(int32_t tx, int32_t ty, int32_t mdens)
bool InsertMaterial(int32_t mat, int32_t *tx, int32_t *ty, int32_t vx=0, int32_t vy=0, bool query_only=false)
C4SRealism Realism
Definition: C4Scenario.h:127
bool LandscapeInsertThrust
Definition: C4Scenario.h:111

References _GetMat(), _GetPix(), C4M_Solid, C4Game::C4S, Game, C4Scenario::Game, GetHeight(), GetMat(), GetWidth(), InsertMaterial(), InsertMaterialOutsideLandscape(), C4SRealism::LandscapeInsertThrust, Mat2PixColDefault(), MatDensity(), MatValid(), Random(), C4SGame::Realism, SetPix2(), and Transparent.

Referenced by C4MassMover::Execute(), and InsertMaterial().

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

◆ InsertMaterial()

bool C4Landscape::InsertMaterial ( int32_t  mat,
int32_t *  tx,
int32_t *  ty,
int32_t  vx = 0,
int32_t  vy = 0,
bool  query_only = false 
)

Definition at line 975 of file C4Landscape.cpp.

976 {
977  assert(tx); assert(ty);
978  int32_t mdens;
979  if (!MatValid(mat)) return false;
980  mdens = std::min(MatDensity(mat), C4M_Solid);
981  if (!mdens) return true;
982 
983  // Bounds
984  if (!Inside<int32_t>(*tx, 0, GetWidth() - 1) || !Inside<int32_t>(*ty, 0, GetHeight())) return InsertMaterialOutsideLandscape(*tx, *ty, mdens);
985 
987  {
988  // Same or higher density?
989  if (GetDensity(*tx, *ty) >= mdens)
990  // Push
991  if (!FindMatPathPush(*tx, *ty, mdens, ::MaterialMap.Map[mat].MaxSlide, !!::MaterialMap.Map[mat].Instable))
992  // Or die
993  return false;
994  }
995  else
996  {
997  // Move up above same density
998  while (mdens == std::min(GetDensity(*tx, *ty), C4M_Solid))
999  {
1000  (*ty)--; if (*ty < 0) return false;
1001  // Primitive slide (1)
1002  if (GetDensity(*tx - 1, *ty) < mdens) (*tx)--;
1003  if (GetDensity(*tx + 1, *ty) < mdens) (*tx)++;
1004  }
1005  // Stuck in higher density
1006  if (GetDensity(*tx, *ty) > mdens) return false;
1007  }
1008 
1009  // Try slide
1010  while (FindMatSlide(*tx, *ty, +1, mdens, ::MaterialMap.Map[mat].MaxSlide))
1011  if (GetDensity(*tx, *ty + 1) < mdens)
1012  {
1013  if (!query_only)
1014  return ::PXS.Create(mat, itofix(*tx), itofix(*ty), C4REAL10(vx), C4REAL10(vy));
1015  return true;
1016  }
1017 
1018  if (query_only)
1019  {
1020  // since tx and ty changed, we need to re-check the bounds here
1021  // if we really inserted it, the check is made again in InsertDeadMaterial
1022  if (!Inside<int32_t>(*tx, 0, GetWidth() - 1) || !Inside<int32_t>(*ty, 0, GetHeight())) return InsertMaterialOutsideLandscape(*tx, *ty, mdens);
1023  return true;
1024  }
1025 
1026  // Try reaction with material below and at insertion position
1027  C4MaterialReaction *pReact; int32_t tmat;
1028  int32_t check_dir = 0;
1029  for (int32_t i = 0; i < 2; ++i)
1030  {
1031  if ((pReact = ::MaterialMap.GetReactionUnsafe(mat, tmat = GetMat(*tx, *ty + check_dir))))
1032  {
1033  C4Real fvx = C4REAL10(vx), fvy = C4REAL10(vy);
1034  if ((*pReact->pFunc)(pReact, *tx, *ty, *tx, *ty + check_dir, fvx, fvy, mat, tmat, meePXSPos, nullptr))
1035  {
1036  // the material to be inserted killed itself in some material reaction below
1037  return true;
1038  }
1039  }
1040  if (!(check_dir = Sign(GravAccel))) break;
1041  }
1042 
1043  // Insert as dead material
1044  return InsertDeadMaterial(mat, *tx, *ty);
1045 }
@ meePXSPos
Definition: C4Material.h:36
#define GravAccel
Definition: C4Physics.h:27
C4Real C4REAL10(int x)
Definition: C4Real.h:269
int Sign(T val)
Definition: Standard.h:45
Definition: C4Real.h:59
bool FindMatPathPush(int32_t &fx, int32_t &fy, int32_t mdens, int32_t mslide, bool liquid) const
bool InsertDeadMaterial(int32_t mat, int32_t tx, int32_t ty)
bool FindMatSlide(int32_t &fx, int32_t &fy, int32_t ydir, int32_t mdens, int32_t mslide) const
C4MaterialReaction * GetReactionUnsafe(int32_t iPXSMat, int32_t iLandscapeMat)
Definition: C4Material.h:191
bool LandscapePushPull
Definition: C4Scenario.h:110
C4MaterialReactionFunc pFunc
Definition: C4Material.h:47

References C4M_Solid, C4REAL10(), C4Game::C4S, C4PXSSystem::Create(), FindMatPathPush(), FindMatSlide(), Game, C4Scenario::Game, GetDensity(), GetHeight(), GetMat(), C4MaterialMap::GetReactionUnsafe(), GetWidth(), GravAccel, InsertDeadMaterial(), InsertMaterialOutsideLandscape(), C4MaterialCore::Instable, itofix(), C4SRealism::LandscapePushPull, C4MaterialMap::Map, MatDensity(), MaterialMap, MatValid(), C4MaterialCore::MaxSlide, meePXSPos, C4MaterialReaction::pFunc, PXS, C4SGame::Realism, and Sign().

Referenced by C4MassMover::Execute(), InsertDeadMaterial(), C4MaterialMap::mrfIncinerate(), and C4MaterialMap::mrfInsert().

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

◆ InsertMaterialOutsideLandscape()

bool C4Landscape::InsertMaterialOutsideLandscape ( int32_t  tx,
int32_t  ty,
int32_t  mdens 
)

Definition at line 967 of file C4Landscape.cpp.

968 {
969  // Out-of-bounds insertion considered successful if inserted into same or lower density
970  // This ensures pumping out of map works
971  // Do allow insertion into same density because it covers the case of e.g. pumping water into the upper ocean of an underwater scenario
972  return GetDensity(tx, ty) <= mdens;
973 }

References GetDensity().

Referenced by InsertDeadMaterial(), and InsertMaterial().

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

◆ Load()

bool C4Landscape::Load ( C4Group hGroup,
bool  fLoadSky,
bool  fSavegame 
)

Definition at line 1831 of file C4Landscape.cpp.

1832 {
1833  assert(!p->Surface8 && !p->Surface8Bkg);
1834 
1835  // Load exact landscape from group
1836  if ((p->Surface8 = GroupReadSurface8(hGroup, C4CFN_Landscape)) == nullptr)
1837  {
1838  if ((p->Surface8 = GroupReadSurface8(hGroup, C4CFN_LandscapeFg)) == nullptr) return false;
1839  p->Surface8Bkg = GroupReadSurface8(hGroup, C4CFN_LandscapeBg);
1840 
1841  if (p->Surface8Bkg)
1842  {
1843  if (p->Surface8->Wdt != p->Surface8Bkg->Wdt || p->Surface8->Hgt != p->Surface8Bkg->Hgt)
1844  {
1845  LogFatal(FormatString("Landscape has different dimensions than background landscape (%dx%d vs. %dx%d)", p->Surface8->Wdt, p->Surface8->Hgt, p->Surface8Bkg->Wdt, p->Surface8Bkg->Hgt).getData());
1846  return false;
1847  }
1848  }
1849  else
1850  {
1851  // LandscapeFg.bmp loaded: Assume full 8bit mat-tex values
1852  // when creating background surface.
1853  p->Surface8Bkg = p->CreateDefaultBkgSurface(*p->Surface8, false);
1854  }
1855  }
1856  else
1857  {
1858  // Landscape.bmp loaded: Assume msb is IFT flag when creating
1859  // background surface.
1860  p->Surface8Bkg = p->CreateDefaultBkgSurface(*p->Surface8, true);
1861  }
1862 
1863  int iWidth, iHeight;
1864  p->Surface8->GetSurfaceSize(iWidth, iHeight);
1865  p->Width = iWidth; p->Height = iHeight;
1866 
1867  // adjust pal
1868  if (!p->Mat2Pal()) return false;
1869  // Landscape should be in correct format: Make sure it is!
1870  for (int32_t y = 0; y < GetHeight(); ++y)
1871  for (int32_t x = 0; x < GetWidth(); ++x)
1872  {
1873  BYTE byPix = p->Surface8->_GetPix(x, y);
1874  int32_t iMat = PixCol2Mat(byPix);
1875 
1876  if (byPix && !MatValid(iMat))
1877  {
1878  LogFatal(FormatString("Landscape loading error at (%d/%d): Pixel value %d not a valid material!", (int)x, (int)y, (int)byPix).getData());
1879  return false;
1880  }
1881 
1882  BYTE byPixBkg = p->Surface8Bkg->_GetPix(x, y);
1883  int32_t iMatBkg = PixCol2Mat(byPixBkg);
1884 
1885  if (byPixBkg && !MatValid(iMatBkg))
1886  {
1887  LogFatal(FormatString("Background Landscape loading error at (%d/%d): Pixel value %d not a valid material!", (int)x, (int)y, (int)byPixBkg).getData());
1888  return false;
1889  }
1890  }
1891 
1892  // Init sky
1893  if (fLoadSky)
1894  {
1895  Game.SetInitProgress(70);
1896  if (p->Sky.Init(fSavegame)) return false;
1897  }
1898  // Success
1899  return true;
1900 }
#define C4CFN_LandscapeFg
Definition: C4Components.h:61
#define C4CFN_Landscape
Definition: C4Components.h:60
#define C4CFN_LandscapeBg
Definition: C4Components.h:62
int32_t PixCol2Mat(BYTE pixc)
bool LogFatal(const char *szMessage)
Definition: C4Log.cpp:239
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:270
const char * getData() const
Definition: StdBuf.h:442

◆ MapToLandscape()

bool C4Landscape::MapToLandscape ( )

Definition at line 2110 of file C4Landscape.cpp.

2111 {
2112  // zoom map to landscape
2113  return p->MapToLandscape(this, *p->Map, *p->MapBkg, 0, 0, p->MapWidth, p->MapHeight);
2114 }

Referenced by C4ToolsDlg::SetLandscapeMode().

Here is the caller graph for this function:

◆ PostInitMap()

bool C4Landscape::PostInitMap ( )

Definition at line 2446 of file C4Landscape.cpp.

2447 {
2448  // map creator present?
2449  if (!p->pMapCreator) return true;
2450  // call scripts
2451  p->pMapCreator->ExecuteCallbacks(p->MapZoom);
2452  // destroy map creator, if not needed later
2453  if (!Game.C4S.Landscape.KeepMapCreator) { p->pMapCreator.reset(); }
2454  // done, success
2455  return true;
2456 }

References C4Game::C4S, Game, C4SLandscape::KeepMapCreator, and C4Scenario::Landscape.

◆ RaiseTerrain()

void C4Landscape::RaiseTerrain ( int32_t  tx,
int32_t  ty,
int32_t  wdt 
)

Definition at line 940 of file C4Landscape.cpp.

941 {
942  int32_t cx, cy;
943  BYTE cpix;
944  for (cx = tx; cx < tx + wdt; cx++)
945  {
946  for (cy = ty; (cy + 1 < ::Landscape.GetHeight()) && !GBackSolid(cx, cy + 1); cy++) {}
947  if (cy + 1 < ::Landscape.GetHeight()) if (cy - ty < 20)
948  {
949  cpix = GetPix(cx, cy + 1);
950  if (!MatVehicle(PixCol2Mat(cpix)))
951  while (cy >= ty) { SetPix2(cx, cy, cpix, GetBackPix(cx, cy + 1)); cy--; }
952  }
953  }
954 }
C4Landscape Landscape
bool MatVehicle(int32_t iMat)
Definition: C4Material.h:215

References GBackSolid(), GetBackPix(), GetHeight(), GetPix(), Landscape, MatVehicle(), PixCol2Mat(), and SetPix2().

Referenced by C4Game::CreateObjectConstruction().

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

◆ RemoveUnusedTexMapEntries()

void C4Landscape::RemoveUnusedTexMapEntries ( )

Definition at line 4151 of file C4Landscape.cpp.

4152 {
4153  // check usage in landscape
4154  bool fTexUsage[C4M_MaxTexIndex];
4155  int32_t iMatTex;
4156  for (iMatTex = 0; iMatTex < C4M_MaxTexIndex; ++iMatTex)
4157  fTexUsage[iMatTex] = false;
4158  for (int32_t y = 0; y < GetHeight(); ++y)
4159  for (int32_t x = 0; x < GetWidth(); ++x)
4160  {
4161  const BYTE pix = p->Surface8->GetPix(x, y);
4162  const BYTE backPix = p->Surface8Bkg->GetPix(x, y);
4163  assert(pix < C4M_MaxTexIndex);
4164  assert(backPix < C4M_MaxTexIndex);
4165 
4166  fTexUsage[pix] = true;
4167  fTexUsage[backPix] = true;
4168  }
4169 
4170  // check usage by materials
4171  for (int32_t iMat = 0; iMat < ::MaterialMap.Num; ++iMat)
4172  {
4173  C4Material *pMat = ::MaterialMap.Map + iMat;
4174  if (pMat->BlastShiftTo >= 0) fTexUsage[pMat->BlastShiftTo] = true;
4175  if (pMat->BelowTempConvertTo >= 0) fTexUsage[pMat->BelowTempConvertTo] = true;
4176  if (pMat->AboveTempConvertTo >= 0) fTexUsage[pMat->AboveTempConvertTo] = true;
4177  if (pMat->DefaultMatTex >= 0) fTexUsage[pMat->DefaultMatTex] = true;
4178  }
4179  // remove unused
4180  for (iMatTex = 1; iMatTex < C4M_MaxTexIndex; ++iMatTex)
4181  if (!fTexUsage[iMatTex])
4182  ::TextureMap.RemoveEntry(iMatTex);
4183  // flag rewrite
4184  ::TextureMap.fEntriesAdded = true;
4185 }
int32_t AboveTempConvertTo
Definition: C4Material.h:154
int32_t BelowTempConvertTo
Definition: C4Material.h:153
int32_t BlastShiftTo
Definition: C4Material.h:151
int32_t DefaultMatTex
Definition: C4Material.h:155
int32_t Num
Definition: C4Material.h:168
bool fEntriesAdded
Definition: C4Texture.h:83
void RemoveEntry(int32_t iIndex)
Definition: C4Texture.cpp:525

References C4Material::AboveTempConvertTo, C4Material::BelowTempConvertTo, C4Material::BlastShiftTo, C4M_MaxTexIndex, C4Material::DefaultMatTex, C4TextureMap::fEntriesAdded, GetHeight(), GetWidth(), C4MaterialMap::Map, MaterialMap, C4MaterialMap::Num, C4TextureMap::RemoveEntry(), TextureMap, CPolyEdge::x, and CPolyEdge::y.

Here is the call graph for this function:

◆ ReplaceMapColor()

bool C4Landscape::ReplaceMapColor ( BYTE  iOldIndex,
BYTE  iNewIndex 
)

Definition at line 4046 of file C4Landscape.cpp.

4047 {
4048  // find every occurance of iOldIndex in map; replace it by new index
4049  if (!p->Map) return false;
4050  int iPitch, iMapWdt, iMapHgt;
4051  BYTE *pMap = p->Map->Bits;
4052  iMapWdt = p->Map->Wdt;
4053  iMapHgt = p->Map->Hgt;
4054  iPitch = p->Map->Pitch;
4055  if (!pMap) return false;
4056  for (int32_t y = 0; y < iMapHgt; ++y)
4057  {
4058  for (int32_t x = 0; x < iMapWdt; ++x)
4059  {
4060  if (*pMap == iOldIndex)
4061  *pMap = iNewIndex;
4062  ++pMap;
4063  }
4064  pMap += iPitch - iMapWdt;
4065  }
4066  return true;
4067 }

References CPolyEdge::x, and CPolyEdge::y.

Referenced by SetTextureIndex().

Here is the caller graph for this function:

◆ Save()

bool C4Landscape::Save ( C4Group hGroup) const

Definition at line 1693 of file C4Landscape.cpp.

1694 {
1696  bool r = p->SaveInternal(this, hGroup);
1698  return r;
1699 }
static void RemoveSolidMasks()
static void PutSolidMasks()

References C4SolidMask::PutSolidMasks(), and C4SolidMask::RemoveSolidMasks().

Referenced by C4Game::LoadScenarioSection().

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

◆ SaveDiff()

bool C4Landscape::SaveDiff ( C4Group hGroup,
bool  fSyncSave 
) const

Definition at line 1734 of file C4Landscape.cpp.

1735 {
1737  bool r = p->SaveDiffInternal(this, hGroup, fSyncSave);
1739  return r;
1740 }

References C4SolidMask::PutSolidMasks(), and C4SolidMask::RemoveSolidMasks().

Here is the call graph for this function:

◆ SaveInitial()

bool C4Landscape::SaveInitial ( )

Definition at line 1810 of file C4Landscape.cpp.

1811 {
1812 
1813  // Create array
1814  p->pInitial = std::make_unique<BYTE[]>(GetWidth() * GetHeight());
1815  p->pInitialBkg = std::make_unique<BYTE[]>(GetWidth() * GetHeight());
1816 
1817  // Save material data
1818  for (int y = 0; y < GetHeight(); y++)
1819  {
1820  const int pitch = y * GetWidth();
1821  for (int x = 0; x < GetWidth(); x++)
1822  {
1823  p->pInitial[pitch + x] = p->Surface8->_GetPix(x, y);
1824  p->pInitialBkg[pitch + x] = p->Surface8Bkg->_GetPix(x, y);
1825  }
1826  }
1827 
1828  return true;
1829 }

References GetHeight(), GetWidth(), CPolyEdge::x, and CPolyEdge::y.

Here is the call graph for this function:

◆ SaveMap()

bool C4Landscape::SaveMap ( C4Group hGroup) const

Definition at line 1954 of file C4Landscape.cpp.

1955 {
1956  // No map
1957  if (!p->Map) return false;
1958  assert(p->MapBkg != nullptr);
1959 
1960  // Create map palette
1961  CStdPalette Palette;
1963 
1964  // Save map surface
1965  if (!p->Map->Save(Config.AtTempPath(C4CFN_TempMapFg), &Palette))
1966  return false;
1967 
1968  // Move temp file to group
1969  if (!hGroup.Move(Config.AtTempPath(C4CFN_TempMapFg),
1970  C4CFN_MapFg))
1971  return false;
1972 
1973  // Save background map surface
1974  if (!p->MapBkg->Save(Config.AtTempPath(C4CFN_TempMapBg), &Palette))
1975  return false;
1976 
1977  // Move temp file to group
1978  if (!hGroup.Move(Config.AtTempPath(C4CFN_TempMapBg),
1979  C4CFN_MapBg))
1980  return false;
1981 
1982  // Success
1983  return true;
1984 }
#define C4CFN_TempMapFg
Definition: C4Components.h:154
#define C4CFN_TempMapBg
Definition: C4Components.h:155
const char * AtTempPath(const char *filename)
Definition: C4Config.cpp:600
bool Move(const char *filename, const char *entry_name)
Definition: C4Group.cpp:1633
void StoreMapPalette(CStdPalette *, C4MaterialMap &rMaterials)
Definition: C4Texture.cpp:537

References C4Config::AtTempPath(), C4CFN_MapBg, C4CFN_MapFg, C4CFN_TempMapBg, C4CFN_TempMapFg, Config, MaterialMap, C4Group::Move(), C4TextureMap::StoreMapPalette(), and TextureMap.

Referenced by C4Landscape::P::SaveDiffInternal(), and C4Landscape::P::SaveInternal().

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

◆ SaveTextures()

bool C4Landscape::SaveTextures ( C4Group hGroup) const

Definition at line 1986 of file C4Landscape.cpp.

1987 {
1988  // if material-texture-combinations have been added, write the texture map
1989  if (::TextureMap.fEntriesAdded)
1990  {
1991  C4Group *pMatGroup = new C4Group();
1992  bool fSuccess = false;
1993  // create local material group
1994  if (!hGroup.FindEntry(C4CFN_Material))
1995  {
1996  // delete previous item at temp path
1998  // create at temp path
1999  if (pMatGroup->Open(Config.AtTempPath(C4CFN_Material), true))
2000  // write to it
2001  if (::TextureMap.SaveMap(*pMatGroup, C4CFN_TexMap))
2002  // close (flush)
2003  if (pMatGroup->Close())
2004  // add it
2006  fSuccess = true;
2007  // temp group must remain for scenario file closure
2008  // it will be deleted when the group is closed
2009  }
2010  else
2011  // simply write it to the local material file
2012  if (pMatGroup->OpenAsChild(&hGroup, C4CFN_Material))
2013  fSuccess = ::TextureMap.SaveMap(*pMatGroup, C4CFN_TexMap);
2014  // close material group again
2015  if (pMatGroup->IsOpen()) pMatGroup->Close();
2016  delete pMatGroup;
2017  // fail if unsuccessful
2018  if (!fSuccess) return false;
2019  }
2020  // done, success
2021  return true;
2022 }
#define C4CFN_Material
Definition: C4Components.h:25
#define C4CFN_TexMap
Definition: C4Components.h:80
bool EraseItem(const char *szItemName)
Definition: StdFile.cpp:833
bool OpenAsChild(C4Group *mother, const char *entry_name, bool is_exclusive=false, bool do_create=false)
Definition: C4Group.cpp:1952
bool IsOpen() const
Definition: C4Group.cpp:2373
bool Close()
Definition: C4Group.cpp:971
bool FindEntry(const char *wildcard, StdStrBuf *filename=nullptr, size_t *size=nullptr)
Definition: C4Group.cpp:2211
bool Open(const char *group_name, bool do_create=false)
Definition: C4Group.cpp:660
bool SaveMap(C4Group &hGroup, const char *szEntryName)
Definition: C4Texture.cpp:309

References C4Config::AtTempPath(), C4CFN_Material, C4CFN_TexMap, C4Group::Close(), Config, EraseItem(), C4TextureMap::fEntriesAdded, C4Group::FindEntry(), C4Group::IsOpen(), C4Group::Move(), C4Group::Open(), C4Group::OpenAsChild(), C4TextureMap::SaveMap(), and TextureMap.

Referenced by C4Landscape::P::SaveDiffInternal(), and C4Landscape::P::SaveInternal().

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

◆ ScenarioInit()

void C4Landscape::ScenarioInit ( )

Definition at line 1351 of file C4Landscape.cpp.

1352 {
1353  // Gravity
1355 }
C4Real C4REAL100(int x)
Definition: C4Real.h:267
C4SVal Gravity
Definition: C4Scenario.h:176

References C4REAL100(), C4Game::C4S, DefaultGravAccel, C4SVal::Evaluate(), Game, C4SLandscape::Gravity, and C4Scenario::Landscape.

Here is the call graph for this function:

◆ SetGravity()

void C4Landscape::SetGravity ( C4Real  g)

Definition at line 3686 of file C4Landscape.cpp.

3687 {
3688  p->Gravity = g;
3689 }

◆ SetMapChanged()

void C4Landscape::SetMapChanged ( )

Definition at line 4149 of file C4Landscape.cpp.

4149 { p->fMapChanged = true; }

Referenced by DrawBox(), DrawBrush(), and DrawLine().

Here is the caller graph for this function:

◆ SetMode()

void C4Landscape::SetMode ( LandscapeMode  iMode)

Definition at line 3390 of file C4Landscape.cpp.

3391 {
3392  p->mode = mode;
3393 }

Referenced by C4ToolsDlg::SetLandscapeMode().

Here is the caller graph for this function:

◆ SetModulation()

bool C4Landscape::SetModulation ( DWORD  dwWithClr)

Definition at line 4019 of file C4Landscape.cpp.

4020 {
4021  p->Modulation = dwWithClr;
4022  return true;
4023 }

◆ SetPix2()

bool C4Landscape::SetPix2 ( int32_t  x,
int32_t  y,
BYTE  fgPix,
BYTE  bgPix 
)

Definition at line 786 of file C4Landscape.cpp.

787 {
788  // check bounds
789  if (x < 0 || y < 0 || x >= GetWidth() || y >= GetHeight())
790  return false;
791  // no change?
792  if ((fgPix == Transparent || fgPix == _GetPix(x, y)) && (bgPix == Transparent || bgPix == p->Surface8Bkg->_GetPix(x, y)))
793  return true;
794  // set pixel
795  return _SetPix2(x, y, fgPix, bgPix);
796 }
bool _SetPix2(int32_t x, int32_t y, BYTE fgPix, BYTE bgPix)

References _GetPix(), _SetPix2(), GetHeight(), GetWidth(), and Transparent.

Referenced by C4Landscape::P::BlastFreePix(), ClearPix(), C4Landscape::P::DoScan(), DrawMaterialRect(), InsertDeadMaterial(), C4SolidMask::Put(), RaiseTerrain(), and C4SolidMask::Repair().

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

◆ SetTextureIndex()

bool C4Landscape::SetTextureIndex ( const char *  szMatTex,
BYTE  iNewIndex,
bool  fInsert 
)

Definition at line 4069 of file C4Landscape.cpp.

4070 {
4071  if (((!szMatTex || !*szMatTex) && !fInsert) || !Inside<int>(iNewIndex, 1, C4M_MaxTexIndex - 1))
4072  {
4073  DebugLogF("Cannot insert new texture %s to index %d: Invalid parameters.", (const char *)szMatTex, (int)iNewIndex);
4074  return false;
4075  }
4076  // get last mat index - returns zero for not found (valid for insertion mode)
4077  StdStrBuf Material, Texture;
4078  Material.CopyUntil(szMatTex, '-'); Texture.Copy(SSearch(szMatTex, "-"));
4079  BYTE iOldIndex = (szMatTex && *szMatTex) ? ::TextureMap.GetIndex(Material.getData(), Texture.getData(), false) : 0;
4080  // insertion mode?
4081  if (fInsert)
4082  {
4083  // there must be room to move up to
4084  BYTE byLastMoveIndex = C4M_MaxTexIndex - 1;
4085  while (::TextureMap.GetEntry(byLastMoveIndex))
4086  if (--byLastMoveIndex == iNewIndex)
4087  {
4088  DebugLogF("Cannot insert new texture %s to index %d: No room for insertion.", (const char *)szMatTex, (int)iNewIndex);
4089  return false;
4090  }
4091  // then move up all other textures first
4092  // could do this in one loop, but it's just a developement call anyway, so move one index at a time
4093  while (--byLastMoveIndex >= iNewIndex)
4094  if (::TextureMap.GetEntry(byLastMoveIndex))
4095  {
4096  ReplaceMapColor(byLastMoveIndex, byLastMoveIndex + 1);
4097  ::TextureMap.MoveIndex(byLastMoveIndex, byLastMoveIndex + 1);
4098  }
4099  // new insertion desired?
4100  if (szMatTex && *szMatTex)
4101  {
4102  // move from old or create new
4103  if (iOldIndex)
4104  {
4105  ReplaceMapColor(iOldIndex, iNewIndex);
4106  ::TextureMap.MoveIndex(iOldIndex, iNewIndex);
4107  }
4108  else
4109  {
4110  StdStrBuf Material, Texture;
4111  Material.CopyUntil(szMatTex, '-'); Texture.Copy(SSearch(szMatTex, "-"));
4112  // new insertion
4113  if (!::TextureMap.AddEntry(iNewIndex, Material.getData(), Texture.getData()))
4114  {
4115  LogF("Cannot insert new texture %s to index %d: Texture map entry error", (const char *)szMatTex, (int)iNewIndex);
4116  return false;
4117  }
4118  }
4119  }
4120  // done, success
4121  return true;
4122  }
4123  else
4124  {
4125  // new index must not be occupied
4126  const C4TexMapEntry *pOld;
4127  if ((pOld = ::TextureMap.GetEntry(iNewIndex)) && !pOld->isNull())
4128  {
4129  DebugLogF("Cannot move texture %s to index %d: Index occupied by %s-%s.", (const char *)szMatTex, (int)iNewIndex, pOld->GetMaterialName(), pOld->GetTextureName());
4130  return false;
4131  }
4132  // must only move existing textures
4133  if (!iOldIndex)
4134  {
4135  DebugLogF("Cannot move texture %s to index %d: Texture not found.", (const char *)szMatTex, (int)iNewIndex);
4136  return false;
4137  }
4138  // update map
4139  ReplaceMapColor(iOldIndex, iNewIndex);
4140  // change to new index in texmap
4141  ::TextureMap.MoveIndex(iOldIndex, iNewIndex);
4142  // done, success
4143  return true;
4144  }
4145 }
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:262
bool DebugLogF(const char *strMessage ...)
Definition: C4Log.cpp:290
const char * SSearch(const char *szString, const char *szIndex)
Definition: Standard.cpp:369
bool ReplaceMapColor(BYTE iOldIndex, BYTE iNewIndex)
Definition: C4Texture.h:49
const char * GetTextureName() const
Definition: C4Texture.h:61
const char * GetMaterialName() const
Definition: C4Texture.h:60
bool isNull() const
Definition: C4Texture.h:59
int32_t GetIndex(const char *szMaterial, const char *szTexture, bool fAddIfNotExist=true, const char *szErrorIfFailed=nullptr)
Definition: C4Texture.cpp:414
void MoveIndex(BYTE byOldIndex, BYTE byNewIndex)
Definition: C4Texture.cpp:403
const C4TexMapEntry * GetEntry(int32_t iIndex) const
Definition: C4Texture.h:85
bool AddEntry(BYTE byIndex, const char *szMaterial, const char *szTexture)
Definition: C4Texture.cpp:103
void CopyUntil(const char *szString, char cUntil)
Definition: StdBuf.h:613
void Copy()
Definition: StdBuf.h:467

References C4TextureMap::AddEntry(), C4M_MaxTexIndex, StdStrBuf::Copy(), StdStrBuf::CopyUntil(), DebugLogF(), StdStrBuf::getData(), C4TextureMap::GetEntry(), C4TextureMap::GetIndex(), C4TexMapEntry::GetMaterialName(), C4TexMapEntry::GetTextureName(), C4TexMapEntry::isNull(), LogF(), C4TextureMap::MoveIndex(), ReplaceMapColor(), SSearch(), and TextureMap.

Here is the call graph for this function:

◆ ShakeFree()

void C4Landscape::ShakeFree ( int32_t  tx,
int32_t  ty,
int32_t  rad 
)

Definition at line 513 of file C4Landscape.cpp.

514 {
515  std::vector<int32_t> vertices(GetRoundPolygon(tx, ty, rad, 50));
516  p->ForPolygon(this, &vertices[0], vertices.size() / 2, [this](int32_t x, int32_t y) { return p->ShakeFreePix(this, x, y); });
517 }

◆ Synchronize()

void C4Landscape::Synchronize ( )

Definition at line 1937 of file C4Landscape.cpp.

1938 {
1939  p->ScanX = 0;
1940 }

Referenced by C4Game::Synchronize().

Here is the caller graph for this function:

◆ UpdatePixMaps()

void C4Landscape::UpdatePixMaps ( )

Definition at line 4226 of file C4Landscape.cpp.

4227 {
4228  int32_t i;
4229  for (i = 0; i < C4M_MaxTexIndex; i++) p->Pix2Mat[i] = PixCol2Mat(i);
4230  for (i = 0; i < C4M_MaxTexIndex; i++) p->Pix2Dens[i] = MatDensity(p->Pix2Mat[i]);
4231  for (i = 0; i < C4M_MaxTexIndex; i++) p->Pix2Place[i] = MatValid(p->Pix2Mat[i]) ? ::MaterialMap.Map[p->Pix2Mat[i]].Placement : 0;
4232  for (i = 0; i < C4M_MaxTexIndex; i++) p->Pix2Light[i] = MatValid(p->Pix2Mat[i]) && (::MaterialMap.Map[p->Pix2Mat[i]].Light>0);
4233  p->Pix2Place[0] = 0;
4234  // clear bridge mat conversion buffers
4235  std::fill(p->BridgeMatConversion.begin(), p->BridgeMatConversion.end(), nullptr);
4236 }
int32_t Placement
Definition: C4Material.h:112
int32_t Light
Definition: C4Material.h:113

References C4M_MaxTexIndex, C4MaterialCore::Light, C4MaterialMap::Map, MatDensity(), MaterialMap, MatValid(), PixCol2Mat(), and C4MaterialCore::Placement.

Referenced by HandleTexMapUpdate(), and Init().

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

Member Data Documentation

◆ Transparent


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