OpenClonk
C4Landscape.cpp File Reference
Include dependency graph for C4Landscape.cpp:

Go to the source code of this file.

Classes

struct  C4Landscape::P
 
struct  CPolyEdge
 

Macros

#define PRETTY_TEMP_CONV
 
#define POLYGON_FIX_SHIFT   16
 

Functions

int32_t PixCol2Mat (BYTE pixc)
 
bool AboveSemiSolid (int32_t &rx, int32_t &ry)
 
bool AboveSolid (int32_t &rx, int32_t &ry)
 
bool SemiAboveSolid (int32_t &rx, int32_t &ry)
 
bool FindLiquidHeight (int32_t cx, int32_t &ry, int32_t hgt)
 
bool FindTunnelHeight (int32_t cx, int32_t &ry, int32_t hgt)
 
bool FindSolidGround (int32_t &rx, int32_t &ry, int32_t width)
 
bool FindSurfaceLiquid (int32_t &rx, int32_t &ry, int32_t width, int32_t height)
 
bool FindLiquid (int32_t &rx, int32_t &ry, int32_t width, int32_t height)
 
bool FindTunnel (int32_t &rx, int32_t &ry, int32_t width, int32_t height)
 
bool FindLevelGround (int32_t &rx, int32_t &ry, int32_t width, int32_t hrange)
 
bool FindConSiteSpot (int32_t &rx, int32_t &ry, int32_t wdt, int32_t hgt, int32_t hrange)
 
bool PathFreePix (int32_t x, int32_t y)
 
bool PathFree (int32_t x1, int32_t y1, int32_t x2, int32_t y2)
 
bool PathFree (int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t *ix, int32_t *iy)
 
bool PathFreeIgnoreVehiclePix (int32_t x, int32_t y)
 
bool PathFreeIgnoreVehicle (int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t *ix, int32_t *iy)
 
int32_t TrajectoryDistance (int32_t iFx, int32_t iFy, C4Real iXDir, C4Real iYDir, int32_t iTx, int32_t iTy)
 
bool FindThrowingPosition (int32_t iTx, int32_t iTy, C4Real fXDir, C4Real fYDir, int32_t iHeight, int32_t &rX, int32_t &rY)
 
bool FindClosestFree (int32_t &rX, int32_t &rY, int32_t iAngle1, int32_t iAngle2, int32_t iExcludeAngle1, int32_t iExcludeAngle2)
 
bool ConstructionCheck (C4PropList *PropList, int32_t iX, int32_t iY, C4Object *pByObj)
 

Variables

const int QuickPolyBufSize = 20
 
CPolyEdge QuickPolyBuf [QuickPolyBufSize]
 
C4Landscape Landscape
 

Class Documentation

◆ CPolyEdge

struct CPolyEdge

Definition at line 1150 of file C4Landscape.cpp.

Collaboration diagram for CPolyEdge:
[legend]
Class Members
int bottom
int dx
struct CPolyEdge * next
struct CPolyEdge * prev
int w
int x
int y

Macro Definition Documentation

◆ POLYGON_FIX_SHIFT

#define POLYGON_FIX_SHIFT   16

Definition at line 1161 of file C4Landscape.cpp.

◆ PRETTY_TEMP_CONV

#define PRETTY_TEMP_CONV

Definition at line 272 of file C4Landscape.cpp.

Function Documentation

◆ AboveSemiSolid()

bool AboveSemiSolid ( int32_t &  rx,
int32_t &  ry 
)

Definition at line 2480 of file C4Landscape.cpp.

2481 {
2482  int32_t cy1 = ry, cy2 = ry;
2483  bool UseUpwardsNextFree = false, UseDownwardsNextSolid = false;
2484 
2485  while ((cy1 >= 0) || (cy2 < ::Landscape.GetHeight()))
2486  {
2487  // Check upwards
2488  if (cy1 >= 0)
2489  {
2490  if (GBackSemiSolid(rx, cy1)) UseUpwardsNextFree = true;
2491  else if (UseUpwardsNextFree) { ry = cy1; return true; }
2492  }
2493  // Check downwards
2494  if (cy2 < ::Landscape.GetHeight())
2495  {
2496  if (!GBackSemiSolid(rx, cy2)) UseDownwardsNextSolid = true;
2497  else if (UseDownwardsNextSolid) { ry = cy2; return true; }
2498  }
2499  // Advance
2500  cy1--; cy2++;
2501  }
2502 
2503  return false;
2504 }
C4Landscape Landscape
bool GBackSemiSolid(int32_t x, int32_t y)
Definition: C4Landscape.h:234
int32_t GetHeight() const

References GBackSemiSolid(), C4Landscape::GetHeight(), and Landscape.

Referenced by FindConSiteSpot(), FindLevelGround(), FindSolidGround(), and FindSurfaceLiquid().

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

◆ AboveSolid()

bool AboveSolid ( int32_t &  rx,
int32_t &  ry 
)

Definition at line 2507 of file C4Landscape.cpp.

2508 {
2509  int32_t cy1 = ry, cy2 = ry;
2510 
2511  while ((cy1 >= 0) || (cy2 < ::Landscape.GetHeight()))
2512  {
2513  // Check upwards
2514  if (cy1 >= 0)
2515  if (!GBackSemiSolid(rx, cy1))
2516  if (GBackSolid(rx, cy1 + 1))
2517  {
2518  ry = cy1; return true;
2519  }
2520  // Check downwards
2521  if (cy2 + 1 < ::Landscape.GetHeight())
2522  if (!GBackSemiSolid(rx, cy2))
2523  if (GBackSolid(rx, cy2 + 1))
2524  {
2525  ry = cy2; return true;
2526  }
2527  // Advance
2528  cy1--; cy2++;
2529  }
2530 
2531  return false;
2532 }
bool GBackSolid(int32_t x, int32_t y)
Definition: C4Landscape.h:229

References GBackSemiSolid(), GBackSolid(), C4Landscape::GetHeight(), and Landscape.

Referenced by FindSolidGround().

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

◆ ConstructionCheck()

bool ConstructionCheck ( C4PropList PropList,
int32_t  iX,
int32_t  iY,
C4Object pByObj 
)

Definition at line 3069 of file C4Landscape.cpp.

3070 {
3071  C4Def *ndef;
3072  // Check def
3073  if (!(ndef = PropList->GetDef()))
3074  {
3075  if (pByObj) GameMsgObjectError(FormatString(LoadResStr("IDS_OBJ_UNDEF"), PropList->GetName()).getData(), pByObj);
3076  return false;
3077  }
3078  // Constructable?
3079  if (!ndef->Constructable)
3080  {
3081  if (pByObj) GameMsgObjectError(FormatString(LoadResStr("IDS_OBJ_NOCON"), ndef->GetName()).getData(), pByObj);
3082  return false;
3083  }
3084  // Check area
3085  int32_t rtx, rty, wdt, hgt;
3086  wdt = ndef->Shape.Wdt; hgt = ndef->Shape.Hgt - ndef->ConSizeOff;
3087  rtx = iX - wdt / 2; rty = iY - hgt;
3088  if (::Landscape.AreaSolidCount(rtx, rty, wdt, hgt) > (wdt*hgt / 20))
3089  {
3090  if (pByObj) GameMsgObjectError(LoadResStr("IDS_OBJ_NOROOM"), pByObj);
3091  return false;
3092  }
3093  if (::Landscape.AreaSolidCount(rtx, rty + hgt, wdt, 5) < (wdt * 2))
3094  {
3095  if (pByObj) GameMsgObjectError(LoadResStr("IDS_OBJ_NOLEVEL"), pByObj);
3096  return false;
3097  }
3098  // Check other structures
3099  C4Object *other;
3100  if ((other = Game.FindConstuctionSiteBlock(rtx, rty, wdt, hgt)))
3101  {
3102  if (pByObj) GameMsgObjectError(FormatString(LoadResStr("IDS_OBJ_NOOTHER"), other->GetName()).getData(), pByObj);
3103  return false;
3104  }
3105  return true;
3106 }
void GameMsgObjectError(const char *szText, C4Object *pTarget, bool Red)
C4Game Game
Definition: C4Globals.cpp:52
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:270
Definition: C4Def.h:99
int32_t ConSizeOff
Definition: C4Def.h:143
int32_t Constructable
Definition: C4Def.h:118
C4Shape Shape
Definition: C4Def.h:104
C4Object * FindConstuctionSiteBlock(int32_t x, int32_t y, int32_t wdt, int32_t hgt)
Definition: C4Game.cpp:1423
int32_t AreaSolidCount(int32_t x, int32_t y, int32_t wdt, int32_t hgt) const
virtual const char * GetName() const
Definition: C4PropList.cpp:618
virtual C4Def const * GetDef() const
Definition: C4PropList.cpp:654
const char * GetName() const override
Definition: C4PropList.cpp:243
int32_t Hgt
Definition: C4Rect.h:30
int32_t Wdt
Definition: C4Rect.h:30
const char * getData() const
Definition: StdBuf.h:442

References C4Landscape::AreaSolidCount(), C4Def::ConSizeOff, C4Def::Constructable, C4Game::FindConstuctionSiteBlock(), FormatString(), Game, GameMsgObjectError(), StdStrBuf::getData(), C4PropList::GetDef(), C4PropList::GetName(), C4PropListStatic::GetName(), C4Rect::Hgt, Landscape, LoadResStr(), C4Def::Shape, and C4Rect::Wdt.

Here is the call graph for this function:

◆ FindClosestFree()

bool FindClosestFree ( int32_t &  rX,
int32_t &  rY,
int32_t  iAngle1,
int32_t  iAngle2,
int32_t  iExcludeAngle1,
int32_t  iExcludeAngle2 
)

Definition at line 3049 of file C4Landscape.cpp.

3051 {
3052  int32_t iX, iY;
3053  for (int32_t iR = Closest_Step; iR < Closest_MaxRange; iR += Closest_Step)
3054  for (int32_t iAngle = iAngle1; iAngle < iAngle2; iAngle += Closest_Step)
3055  if (!Inside(iAngle, iExcludeAngle1, iExcludeAngle2))
3056  {
3057  iX = rX + fixtoi(Sin(itofix(iAngle))*iR);
3058  iY = rY - fixtoi(Cos(itofix(iAngle))*iR);
3059  if (Inside<int32_t>(iX, 0, ::Landscape.GetWidth() - 1))
3060  if (Inside<int32_t>(iY, 0, ::Landscape.GetHeight() - 1))
3061  if (!GBackSemiSolid(iX, iY))
3062  {
3063  rX = iX; rY = iY; return true;
3064  }
3065  }
3066  return false;
3067 }
C4Fixed itofix(int32_t x)
Definition: C4Real.h:261
C4Real Cos(const C4Real &fAngle)
Definition: C4Real.h:266
int fixtoi(const C4Fixed &x)
Definition: C4Real.h:259
C4Real Sin(const C4Real &fAngle)
Definition: C4Real.h:265
bool Inside(T ival, U lbound, V rbound)
Definition: Standard.h:43
int32_t GetWidth() const

Referenced by C4Command::Get().

Here is the caller graph for this function:

◆ FindConSiteSpot()

bool FindConSiteSpot ( int32_t &  rx,
int32_t &  ry,
int32_t  wdt,
int32_t  hgt,
int32_t  hrange 
)

Definition at line 2806 of file C4Landscape.cpp.

2807 {
2808  bool fFound = false;
2809 
2810  // No hrange limit, use standard smooth surface limit
2811  if (hrange == -1) hrange = std::max(wdt / 4, 5);
2812 
2813  int32_t cx1, cx2, cy1, cy2, rh1, rh2, rl1, rl2;
2814 
2815  // Left offset starting position
2816  cx1 = std::min(rx + wdt / 2, ::Landscape.GetWidth() - 1); cy1 = ry;
2817  // No good: use centered starting position
2818  if (!AboveSemiSolid(cx1, cy1)) { cx1 = std::min<int32_t>(rx, ::Landscape.GetWidth() - 1); cy1 = ry; }
2819  // Right offset starting position
2820  cx2 = std::max(rx - wdt / 2, 0); cy2 = ry;
2821  // No good: use centered starting position
2822  if (!AboveSemiSolid(cx2, cy2)) { cx2 = std::min<int32_t>(rx, ::Landscape.GetWidth() - 1); cy2 = ry; }
2823 
2824  rh1 = cy1; rh2 = cy2; rl1 = rl2 = 0;
2825 
2826  for (cx1--, cx2++; (cx1 > 0) || (cx2 < ::Landscape.GetWidth()); cx1--, cx2++)
2827  {
2828  // Left search
2829  if (cx1 > 0) // Still going
2830  {
2831  if (!AboveSemiSolid(cx1, cy1))
2832  cx1 = -1; // Abort left
2833  else
2834  {
2835  if (GBackSolid(cx1, cy1 + 1) && (Abs(cy1 - rh1) < hrange))
2836  rl1++; // Run okay
2837  else
2838  {
2839  rl1 = 0; rh1 = cy1;
2840  } // No run
2841  }
2842  }
2843 
2844  // Right search
2845  if (cx2 < ::Landscape.GetWidth()) // Still going
2846  {
2847  if (!AboveSemiSolid(cx2, cy2))
2848  cx2 = ::Landscape.GetWidth(); // Abort right
2849  else
2850  {
2851  if (GBackSolid(cx2, cy2 + 1) && (Abs(cy2 - rh2) < hrange))
2852  rl2++; // Run okay
2853  else
2854  {
2855  rl2 = 0; rh2 = cy2;
2856  } // No run
2857  }
2858  }
2859 
2860  // Check runs & object overlap
2861  if (rl1 >= wdt) if (cx1 > 0)
2862  if (!Game.FindConstuctionSiteBlock(cx1, cy1 - hgt - 10, wdt, hgt + 40))
2863  {
2864  rx = cx1 + wdt / 2; ry = cy1; fFound = true; break;
2865  }
2866  if (rl2 >= wdt) if (cx2 < ::Landscape.GetWidth())
2867  if (!Game.FindConstuctionSiteBlock(cx2 - wdt, cy2 - hgt - 10, wdt, hgt + 40))
2868  {
2869  rx = cx2 - wdt / 2; ry = cy2; fFound = true; break;
2870  }
2871  }
2872 
2873  if (fFound) AboveSemiSolid(rx, ry);
2874 
2875  return fFound;
2876 }
bool AboveSemiSolid(int32_t &rx, int32_t &ry)
T Abs(T val)
Definition: Standard.h:42

References AboveSemiSolid(), Abs(), C4Game::FindConstuctionSiteBlock(), Game, GBackSolid(), C4Landscape::GetWidth(), and Landscape.

Referenced by C4Player::PlaceReadyBase(), and C4Player::ScenarioInit().

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

◆ FindLevelGround()

bool FindLevelGround ( int32_t &  rx,
int32_t &  ry,
int32_t  width,
int32_t  hrange 
)

Definition at line 2752 of file C4Landscape.cpp.

2753 {
2754  bool fFound = false;
2755 
2756  int32_t cx1, cx2, cy1, cy2, rh1, rh2, rl1, rl2;
2757 
2758  cx1 = cx2 = rx; cy1 = cy2 = ry;
2759  rh1 = cy1; rh2 = cy2;
2760  rl1 = rl2 = 0;
2761 
2762  for (cx1--, cx2++; (cx1 > 0) || (cx2 < ::Landscape.GetWidth()); cx1--, cx2++)
2763  {
2764  // Left search
2765  if (cx1 > 0) // Still going
2766  {
2767  if (!AboveSemiSolid(cx1, cy1)) cx1 = -1; // Abort left
2768  else
2769  {
2770  if (GBackSolid(cx1, cy1 + 1) && (Abs(cy1 - rh1) < hrange))
2771  rl1++; // Run okay
2772  else
2773  {
2774  rl1 = 0; rh1 = cy1;
2775  } // No run
2776  }
2777  }
2778 
2779  // Right search
2780  if (cx2 < ::Landscape.GetWidth()) // Still going
2781  {
2782  if (!AboveSemiSolid(cx2, cy2)) cx2 = ::Landscape.GetWidth(); // Abort right
2783  else
2784  {
2785  if (GBackSolid(cx2, cy2 + 1) && (Abs(cy2 - rh2) < hrange))
2786  rl2++; // Run okay
2787  else
2788  {
2789  rl2 = 0; rh2 = cy2;
2790  } // No run
2791  }
2792  }
2793 
2794  // Check runs
2795  if (rl1 >= width) { rx = cx1 + rl1 / 2; ry = cy1; fFound = true; break; }
2796  if (rl2 >= width) { rx = cx2 - rl2 / 2; ry = cy2; fFound = true; break; }
2797  }
2798 
2799  if (fFound) AboveSemiSolid(rx, ry);
2800 
2801  return fFound;
2802 }

References AboveSemiSolid(), Abs(), GBackSolid(), C4Landscape::GetWidth(), and Landscape.

Referenced by C4Player::PlaceReadyVehic().

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

◆ FindLiquid()

bool FindLiquid ( int32_t &  rx,
int32_t &  ry,
int32_t  width,
int32_t  height 
)

Definition at line 2696 of file C4Landscape.cpp.

2697 {
2698  int32_t cx1, cx2, cy1, cy2, rl1 = 0, rl2 = 0;
2699 
2700  for (cx1 = cx2 = rx, cy1 = cy2 = ry; (cx1 > 0) || (cx2 < ::Landscape.GetWidth()); cx1--, cx2++)
2701  {
2702  // Left search
2703  if (cx1 > 0)
2704  {
2705  if (FindLiquidHeight(cx1, cy1, height)) rl1++;
2706  else rl1 = 0;
2707  }
2708  // Right search
2709  if (cx2 < ::Landscape.GetWidth())
2710  {
2711  if (FindLiquidHeight(cx2, cy2, height)) rl2++;
2712  else rl2 = 0;
2713  }
2714  // Check runs
2715  if (rl1 >= width) { rx = cx1 + rl1 / 2; ry = cy1; return true; }
2716  if (rl2 >= width) { rx = cx2 - rl2 / 2; ry = cy2; return true; }
2717  }
2718 
2719  return false;
2720 }
bool FindLiquidHeight(int32_t cx, int32_t &ry, int32_t hgt)

References FindLiquidHeight(), C4Landscape::GetWidth(), and Landscape.

Referenced by C4Game::PlaceAnimal().

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

◆ FindLiquidHeight()

bool FindLiquidHeight ( int32_t  cx,
int32_t &  ry,
int32_t  hgt 
)

Definition at line 2562 of file C4Landscape.cpp.

2563 {
2564  int32_t cy1 = ry, cy2 = ry, rl1 = 0, rl2 = 0;
2565 
2566  while ((cy1 >= 0) || (cy2 < ::Landscape.GetHeight()))
2567  {
2568  // Check upwards
2569  if (cy1 >= 0)
2570  {
2571  if (GBackLiquid(cx, cy1))
2572  {
2573  rl1++; if (rl1 >= hgt) { ry = cy1 + hgt / 2; return true; }
2574  }
2575  else rl1 = 0;
2576  }
2577  // Check downwards
2578  if (cy2 + 1 < ::Landscape.GetHeight())
2579  {
2580  if (GBackLiquid(cx, cy2))
2581  {
2582  rl2++; if (rl2 >= hgt) { ry = cy2 - hgt / 2; return true; }
2583  }
2584  else rl2 = 0;
2585  }
2586  // Advance
2587  cy1--; cy2++;
2588  }
2589 
2590  return false;
2591 }
bool GBackLiquid(int32_t x, int32_t y)
Definition: C4Landscape.h:239

References GBackLiquid(), C4Landscape::GetHeight(), and Landscape.

Referenced by FindLiquid().

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

◆ FindSolidGround()

bool FindSolidGround ( int32_t &  rx,
int32_t &  ry,
int32_t  width 
)

Definition at line 2626 of file C4Landscape.cpp.

2627 {
2628  bool fFound = false;
2629 
2630  int32_t cx1, cx2, cy1, cy2, rl1 = 0, rl2 = 0;
2631 
2632  for (cx1 = cx2 = rx, cy1 = cy2 = ry; (cx1 > 0) || (cx2 < ::Landscape.GetWidth()); cx1--, cx2++)
2633  {
2634  // Left search
2635  if (cx1 >= 0) // Still going
2636  {
2637  if (AboveSolid(cx1, cy1)) rl1++; // Run okay
2638  else rl1 = 0; // No run
2639  }
2640  // Right search
2641  if (cx2 < ::Landscape.GetWidth()) // Still going
2642  {
2643  if (AboveSolid(cx2, cy2)) rl2++; // Run okay
2644  else rl2 = 0; // No run
2645  }
2646  // Check runs
2647  if (rl1 >= width) { rx = cx1 + rl1 / 2; ry = cy1; fFound = true; break; }
2648  if (rl2 >= width) { rx = cx2 - rl2 / 2; ry = cy2; fFound = true; break; }
2649  }
2650 
2651  if (fFound) AboveSemiSolid(rx, ry);
2652 
2653  return fFound;
2654 }
bool AboveSolid(int32_t &rx, int32_t &ry)

References AboveSemiSolid(), AboveSolid(), C4Landscape::GetWidth(), and Landscape.

Referenced by C4Game::PlaceAnimal(), C4Player::PlaceReadyCrew(), C4Player::PlaceReadyMaterial(), and C4Player::ScenarioInit().

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

◆ FindSurfaceLiquid()

bool FindSurfaceLiquid ( int32_t &  rx,
int32_t &  ry,
int32_t  width,
int32_t  height 
)

Definition at line 2656 of file C4Landscape.cpp.

2657 {
2658  bool fFound = false;
2659 
2660  int32_t cx1, cx2, cy1, cy2, rl1 = 0, rl2 = 0, cnt;
2661  bool lokay;
2662  for (cx1 = cx2 = rx, cy1 = cy2 = ry; (cx1 > 0) || (cx2 < ::Landscape.GetWidth()); cx1--, cx2++)
2663  {
2664  // Left search
2665  if (cx1 > 0) // Still going
2666  {
2667  if (!AboveSemiSolid(cx1, cy1)) cx1 = -1; // Abort left
2668  else
2669  {
2670  for (lokay = true, cnt = 0; cnt < height; cnt++) if (!GBackLiquid(cx1, cy1 + 1 + cnt)) lokay = false;
2671  if (lokay) rl1++; // Run okay
2672  else rl1 = 0; // No run
2673  }
2674  }
2675  // Right search
2676  if (cx2 < ::Landscape.GetWidth()) // Still going
2677  {
2678  if (!AboveSemiSolid(cx2, cy2)) cx2 = ::Landscape.GetWidth(); // Abort right
2679  else
2680  {
2681  for (lokay = true, cnt = 0; cnt < height; cnt++) if (!GBackLiquid(cx2, cy2 + 1 + cnt)) lokay = false;
2682  if (lokay) rl2++; // Run okay
2683  else rl2 = 0; // No run
2684  }
2685  }
2686  // Check runs
2687  if (rl1 >= width) { rx = cx1 + rl1 / 2; ry = cy1; fFound = true; break; }
2688  if (rl2 >= width) { rx = cx2 - rl2 / 2; ry = cy2; fFound = true; break; }
2689  }
2690 
2691  if (fFound) AboveSemiSolid(rx, ry);
2692 
2693  return fFound;
2694 }

References AboveSemiSolid(), GBackLiquid(), C4Landscape::GetWidth(), and Landscape.

Referenced by C4Game::PlaceAnimal().

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

◆ FindThrowingPosition()

bool FindThrowingPosition ( int32_t  iTx,
int32_t  iTy,
C4Real  fXDir,
C4Real  fYDir,
int32_t  iHeight,
int32_t &  rX,
int32_t &  rY 
)

Definition at line 3014 of file C4Landscape.cpp.

3015 {
3016 
3017  // Start underneath throwing target
3018  rX = iTx; rY = iTy; // improve: check from overhanging cliff
3019  if (!SemiAboveSolid(rX, rY)) return false;
3020 
3021  // Target too far above surface
3022  if (!Inside(rY - iTy, -Throwing_MaxVertical, +Throwing_MaxVertical)) return false;
3023 
3024  // Search in direction according to launch fXDir
3025  int32_t iDir = +1; if (fXDir > 0) iDir = -1;
3026 
3027  // Move along surface
3028  for (int32_t cnt = 0; Inside<int32_t>(rX, 0, ::Landscape.GetWidth() - 1) && (cnt <= Throwing_MaxHorizontal); rX += iDir, cnt++)
3029  {
3030  // Adjust to surface
3031  if (!SemiAboveSolid(rX, rY)) return false;
3032 
3033  // Check trajectory distance
3034  int32_t itjd = TrajectoryDistance(rX, rY - iHeight, fXDir, fYDir, iTx, iTy);
3035 
3036  // Hitting range: success
3037  if (itjd <= 2) return true;
3038  }
3039 
3040  // Failure
3041  return false;
3042 
3043 }
int32_t TrajectoryDistance(int32_t iFx, int32_t iFy, C4Real iXDir, C4Real iYDir, int32_t iTx, int32_t iTy)
bool SemiAboveSolid(int32_t &rx, int32_t &ry)

References Inside(), and SemiAboveSolid().

Referenced by C4Command::Put(), and C4Command::Throw().

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

◆ FindTunnel()

bool FindTunnel ( int32_t &  rx,
int32_t &  ry,
int32_t  width,
int32_t  height 
)

Definition at line 2724 of file C4Landscape.cpp.

2725 {
2726  int32_t cx1, cx2, cy1, cy2, rl1 = 0, rl2 = 0;
2727 
2728  for (cx1 = cx2 = rx, cy1 = cy2 = ry; (cx1 > 0) || (cx2 < ::Landscape.GetWidth()); cx1--, cx2++)
2729  {
2730  // Left search
2731  if (cx1 > 0)
2732  {
2733  if (FindTunnelHeight(cx1, cy1, height)) rl1++;
2734  else rl1 = 0;
2735  }
2736  // Right search
2737  if (cx2 < ::Landscape.GetWidth())
2738  {
2739  if (FindTunnelHeight(cx2, cy2, height)) rl2++;
2740  else rl2 = 0;
2741  }
2742  // Check runs
2743  if (rl1 >= width) { rx = cx1 + rl1 / 2; ry = cy1; return true; }
2744  if (rl2 >= width) { rx = cx2 - rl2 / 2; ry = cy2; return true; }
2745  }
2746 
2747  return false;
2748 }
bool FindTunnelHeight(int32_t cx, int32_t &ry, int32_t hgt)

References FindTunnelHeight(), C4Landscape::GetWidth(), and Landscape.

Here is the call graph for this function:

◆ FindTunnelHeight()

bool FindTunnelHeight ( int32_t  cx,
int32_t &  ry,
int32_t  hgt 
)

Definition at line 2593 of file C4Landscape.cpp.

2594 {
2595  int32_t cy1 = ry, cy2 = ry, rl1 = 0, rl2 = 0;
2596 
2597  while ((cy1 >= 0) || (cy2 < ::Landscape.GetHeight()))
2598  {
2599  // Check upwards
2600  if (cy1 >= 0)
2601  {
2602  if (Landscape.GetBackPix(cx, cy1) != 0 && MatDensity(GBackMat(cx, cy1)) < C4M_Liquid)
2603  {
2604  rl1++; if (rl1 >= hgt) { ry = cy1 + hgt / 2; return true; }
2605  }
2606  else rl1 = 0;
2607  }
2608  // Check downwards
2609  if (cy2 + 1 < ::Landscape.GetHeight())
2610  {
2611  if (Landscape.GetBackPix(cx, cy2) != 0 && MatDensity(GBackMat(cx, cy2)) < C4M_Liquid)
2612  {
2613  rl2++; if (rl2 >= hgt) { ry = cy2 - hgt / 2; return true; }
2614  }
2615  else rl2 = 0;
2616  }
2617  // Advance
2618  cy1--; cy2++;
2619  }
2620 
2621  return false;
2622 }
const int32_t C4M_Liquid
Definition: C4Constants.h:174
int32_t GBackMat(int32_t x, int32_t y)
Definition: C4Landscape.h:219
int32_t MatDensity(int32_t mat)
Definition: C4Material.h:240
BYTE GetBackPix(int32_t x, int32_t y) const

References C4M_Liquid, GBackMat(), C4Landscape::GetBackPix(), C4Landscape::GetHeight(), Landscape, and MatDensity().

Referenced by FindTunnel().

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

◆ PathFree() [1/2]

bool PathFree ( int32_t  x1,
int32_t  y1,
int32_t  x2,
int32_t  y2 
)

Definition at line 2884 of file C4Landscape.cpp.

2885 {
2886  return ForLine(x1, y1, x2, y2, &PathFreePix);
2887 }
bool PathFreePix(int32_t x, int32_t y)

References PathFreePix().

Referenced by C4Command::Get(), C4Command::JumpControl(), C4Shape::LineConnect(), C4Command::MoveTo(), and ReduceLineSegments().

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

◆ PathFree() [2/2]

bool PathFree ( int32_t  x1,
int32_t  y1,
int32_t  x2,
int32_t  y2,
int32_t *  ix,
int32_t *  iy 
)

Definition at line 2889 of file C4Landscape.cpp.

2890 {
2891  // use the standard Bresenham algorithm and just adjust it to behave correctly in the inversed case
2892  bool reverse = false;
2893  bool steep = Abs(y2 - y1) > Abs(x2 - x1);
2894 
2895  if (steep)
2896  {
2897  std::swap(x1, y1);
2898  std::swap(x2, y2);
2899  }
2900 
2901  if (x1 > x2)
2902  {
2903  std::swap(x1, x2);
2904  std::swap(y1, y2);
2905  reverse = true;
2906  }
2907 
2908  if (!reverse)
2909  {
2910  int32_t deltax = x2 - x1;
2911  int32_t deltay = Abs(y2 - y1);
2912  int32_t error = 0;
2913  int32_t ystep = (y1 < y2) ? 1 : -1;
2914  int32_t y = y1;
2915 
2916  for (int32_t x = x1; x <= x2; x++)
2917  {
2918  if (steep)
2919  {
2920  if (GBackSolid(y, x))
2921  {
2922  if (ix) { *ix = y; *iy = x; }
2923  return false;
2924  }
2925  }
2926  else
2927  {
2928  if (GBackSolid(x, y))
2929  {
2930  if (ix) { *ix = x; *iy = y; }
2931  return false;
2932  }
2933  }
2934 
2935  error += deltay;
2936  if (2 * error >= deltax)
2937  {
2938  y += ystep;
2939  error -= deltax;
2940  }
2941  }
2942  }
2943  else // reverse
2944  {
2945  int32_t deltax = x2 - x1;
2946  int32_t deltay = Abs(y2 - y1);
2947  int32_t error = 0;
2948  int32_t ystep = (y1 < y2) ? 1 : -1;
2949  int32_t y = y2;
2950 
2951  // normal (inverse) routine
2952  for (int32_t x = x2; x >= x1; x--)
2953  {
2954  if (steep)
2955  {
2956  if (GBackSolid(y, x))
2957  {
2958  if (ix) { *ix = y; *iy = x; }
2959  return false;
2960  }
2961  }
2962  else
2963  {
2964  if (GBackSolid(x, y))
2965  {
2966  if (ix) { *ix = x; *iy = y; }
2967  return false;
2968  }
2969  }
2970 
2971  error -= deltay;
2972  if (2 * error <= -deltax)
2973  {
2974  y -= ystep;
2975  error += deltax;
2976  }
2977 
2978  }
2979  }
2980  // no solid material encountered: path free!
2981  return true;
2982 }

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

Here is the call graph for this function:

◆ PathFreeIgnoreVehicle()

bool PathFreeIgnoreVehicle ( int32_t  x1,
int32_t  y1,
int32_t  x2,
int32_t  y2,
int32_t *  ix,
int32_t *  iy 
)

Definition at line 2990 of file C4Landscape.cpp.

2991 {
2992  return ForLine(x1, y1, x2, y2, &PathFreeIgnoreVehiclePix, ix, iy);
2993 }
bool PathFreeIgnoreVehiclePix(int32_t x, int32_t y)

References PathFreeIgnoreVehiclePix().

Referenced by C4Shape::LineConnect().

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

◆ PathFreeIgnoreVehiclePix()

bool PathFreeIgnoreVehiclePix ( int32_t  x,
int32_t  y 
)

Definition at line 2984 of file C4Landscape.cpp.

2985 {
2986  BYTE byPix = ::Landscape.GetPix(x, y);
2987  return !byPix || !DensitySolid(::Landscape.GetPixMat(byPix)) || ::Landscape.GetPixMat(byPix) == MVehic;
2988 }
bool DensitySolid(int32_t dens)
Definition: C4Landscape.h:196
int32_t MVehic
Definition: C4Material.cpp:36
uint8_t BYTE
BYTE GetPix(int32_t x, int32_t y) const
int32_t GetPixMat(BYTE byPix) const

References DensitySolid(), C4Landscape::GetPix(), C4Landscape::GetPixMat(), Landscape, MVehic, CPolyEdge::x, and CPolyEdge::y.

Referenced by PathFreeIgnoreVehicle().

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

◆ PathFreePix()

bool PathFreePix ( int32_t  x,
int32_t  y 
)

Definition at line 2879 of file C4Landscape.cpp.

2880 {
2881  return !GBackSolid(x, y);
2882 }

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

Referenced by PathFree().

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

◆ PixCol2Mat()

int32_t PixCol2Mat ( BYTE  pixc)

Definition at line 1943 of file C4Landscape.cpp.

1944 {
1945  // Get texture
1946  int32_t iTex = PixCol2Tex(pixc);
1947  if (!iTex) return MNone;
1948  // Get material-texture mapping
1949  const C4TexMapEntry *pTex = ::TextureMap.GetEntry(iTex);
1950  // Return material
1951  return pTex ? pTex->GetMaterialIndex() : MNone;
1952 }
const int32_t MNone
Definition: C4Constants.h:177
int32_t PixCol2Tex(BYTE pixc)
Definition: C4Landscape.h:211
C4TextureMap TextureMap
Definition: C4Texture.cpp:576
Definition: C4Texture.h:49
int32_t GetMaterialIndex() const
Definition: C4Texture.h:62
const C4TexMapEntry * GetEntry(int32_t iIndex) const
Definition: C4Texture.h:85

References C4TextureMap::GetEntry(), C4TexMapEntry::GetMaterialIndex(), MNone, PixCol2Tex(), and TextureMap.

Referenced by C4Landscape::P::DoScan(), C4Landscape::RaiseTerrain(), and C4Landscape::UpdatePixMaps().

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

◆ SemiAboveSolid()

bool SemiAboveSolid ( int32_t &  rx,
int32_t &  ry 
)

Definition at line 2535 of file C4Landscape.cpp.

2536 {
2537  int32_t cy1 = ry, cy2 = ry;
2538 
2539  while ((cy1 >= 0) || (cy2 < ::Landscape.GetHeight()))
2540  {
2541  // Check upwards
2542  if (cy1 >= 0)
2543  if (!GBackSolid(rx, cy1))
2544  if (GBackSolid(rx, cy1 + 1))
2545  {
2546  ry = cy1; return true;
2547  }
2548  // Check downwards
2549  if (cy2 + 1 < ::Landscape.GetHeight())
2550  if (!GBackSolid(rx, cy2))
2551  if (GBackSolid(rx, cy2 + 1))
2552  {
2553  ry = cy2; return true;
2554  }
2555  // Advance
2556  cy1--; cy2++;
2557  }
2558 
2559  return false;
2560 }

References GBackSolid(), C4Landscape::GetHeight(), and Landscape.

Referenced by FindThrowingPosition().

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

◆ TrajectoryDistance()

int32_t TrajectoryDistance ( int32_t  iFx,
int32_t  iFy,
C4Real  iXDir,
C4Real  iYDir,
int32_t  iTx,
int32_t  iTy 
)

Definition at line 2995 of file C4Landscape.cpp.

2996 {
2997  int32_t iClosest = Distance(iFx, iFy, iTx, iTy);
2998  // Follow free trajectory, take closest point distance
2999  C4Real cx = itofix(iFx), cy = itofix(iFy);
3000  int32_t cdis;
3001  while (Inside(fixtoi(cx), 0, ::Landscape.GetWidth() - 1) && Inside(fixtoi(cy), 0, ::Landscape.GetHeight() - 1) && !GBackSolid(fixtoi(cx), fixtoi(cy)))
3002  {
3003  cdis = Distance(fixtoi(cx), fixtoi(cy), iTx, iTy);
3004  if (cdis < iClosest) iClosest = cdis;
3005  cx += iXDir; cy += iYDir; iYDir += GravAccel;
3006  }
3007  return iClosest;
3008 }
#define GravAccel
Definition: C4Physics.h:27
int32_t Distance(int32_t iX1, int32_t iY1, int32_t iX2, int32_t iY2)
Definition: Standard.cpp:25
Definition: C4Real.h:59

References Distance(), fixtoi(), GBackSolid(), C4Landscape::GetHeight(), C4Landscape::GetWidth(), GravAccel, Inside(), itofix(), and Landscape.

Here is the call graph for this function:

Variable Documentation

◆ Landscape

C4Landscape Landscape

Definition at line 4350 of file C4Landscape.cpp.

Referenced by AboveSemiSolid(), AboveSolid(), C4TextureMap::AddEntry(), AdjustMoveToTarget(), C4Viewport::AdjustPosition(), C4EditCursor::ApplyToolBrush(), C4EditCursor::ApplyToolFill(), C4EditCursor::ApplyToolLine(), C4EditCursor::ApplyToolPicker(), C4EditCursor::ApplyToolRect(), C4ToolsDlg::AssertValidBackTexture(), C4ToolsDlg::AssertValidTexture(), C4Viewport::CalculateZoom(), C4Viewport::CenterPosition(), C4SolidMask::CheckConsistency(), C4Game::Clear(), C4Game::ClearPointers(), C4Game::CompileFunc(), ConstructionCheck(), C4Shape::ContactCheck(), C4FoWAmbient::CreateFromLandscape(), C4Game::CreateObjectConstruction(), C4Game::Default(), C4GraphicsSystem::DoSaveScreenshot(), C4Landscape::P::DoScan(), C4PXSSystem::Draw(), C4Viewport::Draw(), C4TextureShape::Draw(), C4Viewport::EnableFoW(), C4Object::ExecMovement(), C4Game::Execute(), C4MassMover::Execute(), C4PXS::Execute(), C4Player::Execute(), FindConSiteSpot(), FindLevelGround(), FindLiquid(), FindLiquidHeight(), FindSolidGround(), FindSurfaceLiquid(), FindTunnel(), FindTunnelHeight(), C4Sky::GetSkyFadeClr(), C4Weather::GetWind(), C4Player::Init(), C4MassMover::Init(), C4Game::InitInEarth(), C4Game::InitVegetation(), C4Viewport::InitZoom(), LandscapeFree(), C4Game::LoadScenarioSection(), C4MaterialMap::mrfCorrode(), C4MaterialMap::mrfIncinerate(), C4MaterialMap::mrfInsert(), mrfInsertCheck(), C4MaterialMap::mrfPoof(), PathFreeIgnoreVehiclePix(), C4Game::PlaceAnimal(), C4Game::PlaceInEarth(), C4SolidMask::Put(), C4SolidMask::PutSolidMasks(), C4SolidMask::PutTemporary(), C4Landscape::RaiseTerrain(), C4SolidMask::Remove(), C4SolidMask::RemoveSolidMasks(), C4SolidMask::RemoveTemporary(), C4SolidMask::Repair(), C4Console::SaveScenario(), C4Player::ScenarioInit(), C4Player::ScrollView(), SemiAboveSolid(), C4ToolsDlg::SetBackMaterial(), C4ToolsDlg::SetLandscapeMode(), C4ToolsDlg::SetMaterial(), C4Viewport::SetViewX(), C4Viewport::SetViewY(), C4Object::SideBounds(), SimFlight(), C4Object::StatusDeactivate(), C4Game::Synchronize(), TrajectoryDistance(), C4FoWLightSection::Update(), C4MouseControl::UpdateFogOfWar(), C4FoWAmbient::UpdateFromLandscape(), C4Object::UpdateLight(), C4EditCursor::UpdateStatusBar(), and C4Object::VerticalBounds().

◆ QuickPolyBuf

CPolyEdge QuickPolyBuf[QuickPolyBufSize]

Definition at line 1214 of file C4Landscape.cpp.

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

◆ QuickPolyBufSize

const int QuickPolyBufSize = 20

Definition at line 1213 of file C4Landscape.cpp.

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