Add a new variant of vehicle that can be passed from below but be walked on from above.

lights3
Julius Michaelis 2015-08-30 22:19:36 +09:00
parent 05a78138a3
commit 2a9b481087
13 changed files with 157 additions and 46 deletions

View File

@ -0,0 +1,5 @@
[Material]
Name=HalfVehicle
Density=100
Friction=100
KeepSinglePixels=1

View File

@ -30,8 +30,67 @@ global func VerticesStuck()
// Returns whether the object has a vertex with the given CNAT value
global func HasCNAT(int cnat)
{
for(var i = -1; i < GetVertexNum(); i++)
for (var i = -1; i < GetVertexNum(); i++)
if (GetVertex(i, VTX_CNAT) == cnat)
return true;
return false;
}
}
// e.g. clonk->SetVertexCNAT(2, CNAT_CollideHalfVehicle, true); makes the clonk behave correctly wrt. to HalfVehicle
global func SetVertexCNAT(int vtx, int val, bool set)
{
if (val == nil || set == nil)
return FatalError("this function requires its second and third parameter to be non-nil");
if (!this)
return FatalError("this function requires object context");
if (vtx == nil)
for (var i = GetVertexNum(); i-->0;)
SetVertexCNAT(i, val, set);
else
SetVertex(vtx, VTX_CNAT, GetVertex(vtx, VTX_CNAT) & ~val | (set && val), 2);
}
// Allow falling down throughg a HalfVehicle platform
global func HalfVehicleFadeJump()
{
if (!this)
return FatalError("this function requires object context");
AddEffect("IntHalfVehicleFadeJump", this, 1, 1);
}
global func FxIntHalfVehicleFadeJumpStart(object target, proplist effect, int temp)
{
if (temp)
return FX_OK;
if (!target) {
return FX_Start_Deny;
}
effect.collideverts = CreateArray();
for (var i = target->GetVertexNum(); i-->0;)
if(target->GetVertex(i, VTX_CNAT) & CNAT_CollideHalfVehicle) {
PushBack(effect.collideverts, i);
target->SetVertexCNAT(i, CNAT_CollideHalfVehicle, false);
}
effect.origpos = target->GetPosition();
return FX_OK;
}
global func FxIntHalfVehicleFadeJumpTimer(object target, proplist effect, int time)
{
if (DeepEqual(target->GetPosition(), effect.origpos))
return FX_OK;
for (var i = GetLength(effect.collideverts); i-->0;) {
if (target->GetMaterial(target->GetVertex(effect.collideverts[i], VTX_X),
target->GetVertex(effect.collideverts[i], VTX_Y)) == Material("HalfVehicle"))
return FX_OK;
}
return FX_Execute_Kill;
}
global func FxIntHalfVehicleFadeJumpStop(object target, proplist effect, int reason, bool temp)
{
if (reason == FX_Call_RemoveClear)
return;
for (var i = GetLength(effect.collideverts); i-->0;)
target->SetVertexCNAT(effect.collideverts[i], CNAT_CollideHalfVehicle, true);
}

View File

@ -129,9 +129,10 @@ const BYTE // Directional
CNAT_Center = 16,
// Additional flags
CNAT_MultiAttach = 32, // new attachment behaviour; see C4Shape::Attach
CNAT_NoCollision = 64; // turn off collision for this vertex
CNAT_NoCollision = 64, // turn off collision for this vertex
CNAT_CollideHalfVehicle = 128;
const BYTE CNAT_Flags = CNAT_MultiAttach | CNAT_NoCollision; // all attchment flags that can be combined with regular attachment
const BYTE CNAT_Flags = CNAT_MultiAttach | CNAT_NoCollision | CNAT_CollideHalfVehicle; // all attchment flags that can be combined with regular attachment
//=============================== Keyboard Input Controls =====================================================

View File

@ -34,9 +34,9 @@
#include <C4Physics.h> // For GravAccel
int32_t MVehic=MNone,MTunnel=MNone,MWater=MNone,MEarth=MNone;
int32_t MVehic=MNone,MHalfVehic=MNone,MTunnel=MNone,MWater=MNone,MEarth=MNone;
BYTE MCVehic=0;
BYTE MCHalfVehic=0;
// -------------------------------------- C4MaterialReaction
@ -677,10 +677,11 @@ bool C4MaterialMap::CrossMapMaterials(const char* szEarthMaterial) // Called aft
if(!earth_entry)
{ LogFatal(FormatString("Earth material \"%s\" not found!", szEarthMaterial).getData()); return false; }
MVehic = Get("Vehicle"); MCVehic = Mat2PixColDefault(MVehic);
MTunnel = Get("Tunnel");
MWater = Get("Water");
MEarth = Get(earth_entry->GetMaterialName());
MVehic = Get("Vehicle"); MCVehic = Mat2PixColDefault(MVehic);
MHalfVehic = Get("HalfVehicle"); MCHalfVehic = Mat2PixColDefault(MHalfVehic);
MTunnel = Get("Tunnel");
MWater = Get("Water");
MEarth = Get(earth_entry->GetMaterialName());
if ((MVehic==MNone) || (MTunnel==MNone))
{ LogFatal(LoadResStr("IDS_PRC_NOSYSMATS")); return false; }

View File

@ -263,6 +263,7 @@ const int32_t MNone = -1;
extern int32_t MVehic,MTunnel,MWater,MEarth; // presearched materials
extern BYTE MCVehic; // precalculated material color
extern BYTE MCHalfVehic; // precalculated material color
inline bool MatValid(int32_t mat)
{
@ -274,6 +275,16 @@ inline bool MatVehicle(int32_t iMat)
return iMat == MVehic;
}
inline bool IsMCVehicle(BYTE mat) {
return mat == MCVehic;
}
inline bool IsMCHalfVehicle(BYTE mat) {
return mat == MCHalfVehic;
}
inline bool IsSomeVehicle(BYTE mat) {
return IsMCVehicle(mat) || IsMCHalfVehicle(mat);
}
inline BYTE MatTex2PixCol(int32_t tex)
{
return BYTE(tex);

View File

@ -96,11 +96,11 @@ void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRes
byPixel=GBackPix(iTx,iTy);
// store it. If MCVehic, also store in initial put, but won't be used in restore
// do not overwrite current value in re-put issued by SolidMask-remover
if (byPixel != MCVehic || RegularPut)
if (!IsSomeVehicle(byPixel) || RegularPut)
pSolidMaskMatBuff[(ycnt+pClipRect->ty)*MatBuffPitch+xcnt+pClipRect->tx]=byPixel;
}
// and set mask
::Landscape.SetPix2(iTx,iTy,MCVehic,::Landscape.Transparent);
::Landscape.SetPix2(iTx,iTy,MaskMaterial,::Landscape.Transparent);
}
else
// no SolidMask: mark buffer as unused here
@ -162,11 +162,11 @@ void C4SolidMask::Put(bool fCauseInstability, C4TargetRect *pClipRect, bool fRes
byPixel=_GBackPix(iTx,iTy);
// store it. If MCVehic, also store in initial put, but won't be used in restore
// do not overwrite current value in re-put issued by SolidMask-remover
if (byPixel != MCVehic || RegularPut)
if (IsSomeVehicle(byPixel) || RegularPut)
pSolidMaskMatBuff[i + xcnt] = byPixel;
}
// set mask pix
::Landscape.SetPix2(iTx, iTy, MCVehic, ::Landscape.Transparent);
::Landscape.SetPix2(iTx, iTy, MaskMaterial, ::Landscape.Transparent);
}
else if (!MaskPut)
// mark pix as unused in buf
@ -229,7 +229,7 @@ int32_t C4SolidMask::DensityProvider::GetDensity(int32_t x, int32_t y) const
// Using put-buffer for rotated masks
// for SolidMask-pixels not put because there was another SolidMask already, this will not return solid
pix=*(rSolidMaskData.pSolidMaskMatBuff+(y+rSolidMaskData.MaskPutRect.ty)*rSolidMaskData.MatBuffPitch+rSolidMaskData.MaskPutRect.tx+x);
if (pix == MCVehic)
if (IsSomeVehicle(pix))
return 0;
else
return C4M_Solid;
@ -259,8 +259,8 @@ void C4SolidMask::Remove(bool fBackupAttachment)
// The pPix-check ensures that only pixels that hads been overwritten by this SolidMask are restored
// Non-SolidMask-pixels should not happen here, because all relevant landscape change routines should
// temp remove SolidMasks before
assert(_GBackPix(iTx,iTy) == MCVehic);
if (::Landscape._GetPix(iTx, iTy) == MCVehic)
assert(IsSomeVehicle(_GBackPix(iTx,iTy)));
if (IsSomeVehicle(::Landscape._GetPix(iTx, iTy)))
::Landscape._SetPix2(iTx, iTy, *pPix, ::Landscape.Transparent);
// Instability
::Landscape.CheckInstabilityRange(iTx,iTy);
@ -340,10 +340,10 @@ void C4SolidMask::RemoveTemporary(C4Rect where)
{
BYTE *pPix = pSolidMaskMatBuff + (y - MaskPutRect.y + MaskPutRect.ty) * MatBuffPitch + x - MaskPutRect.x + MaskPutRect.tx;
// only if mask was used here
if (*pPix != MCVehic)
if (*pPix != MCVehic) //
{
// restore
assert(GBackPix(x,y)==MCVehic);
assert(IsSomeVehicle(GBackPix(x,y)));
::Landscape.SetPix2(x, y, *pPix, ::Landscape.Transparent);
}
}
@ -365,7 +365,7 @@ void C4SolidMask::PutTemporary(C4Rect where)
{
// put
assert(GBackPix(x,y)==*pPix);
::Landscape.SetPix2(x, y, MCVehic, ::Landscape.Transparent);
::Landscape.SetPix2(x, y, MaskMaterial, ::Landscape.Transparent);
}
}
}
@ -387,7 +387,7 @@ void C4SolidMask::Repair(C4Rect where)
// record changed landscape in MatBuff
*pPix = GBackPix(x,y);
// put
::Landscape.SetPix2(x, y, MCVehic, ::Landscape.Transparent);
::Landscape.SetPix2(x, y, MaskMaterial, ::Landscape.Transparent);
}
}
}
@ -401,6 +401,7 @@ C4SolidMask::C4SolidMask(C4Object *pForObject) : pForObject(pForObject)
MaskRemovalX=MaskRemovalY=Fix0;
ppAttachingObjects=NULL;
iAttachingObjectsCount=iAttachingObjectsCapacity=0;
MaskMaterial=MCVehic;
// Update linked list
Next = 0;
Prev = Last;
@ -455,6 +456,7 @@ C4SolidMask * C4SolidMask::Last = 0;
bool C4SolidMask::CheckConsistency()
{
assert(IsSomeVehicle(MaskMaterial));
C4Rect SolidMaskRect(0,0,GBackWdt,GBackHgt);
C4SolidMask *pSolid;
for (pSolid = C4SolidMask::Last; pSolid; pSolid = pSolid->Prev)
@ -487,3 +489,8 @@ CSurface8 *C4SolidMask::LoadMaskFromFile(class C4Group &hGroup, const char *szFi
return result;
}
void C4SolidMask::SetHalfVehicle(bool set)
{
MaskMaterial = set ? MCHalfVehic : MCVehic;
// TODO: Redraw
}

View File

@ -35,7 +35,9 @@ protected:
C4TargetRect MaskPutRect; // absolute bounding screen rect at which the mask is put - tx and ty are offsets within pSolidMask (for rects outside the landscape)
BYTE *pSolidMaskMatBuff; // material replaced by this solidmask. MCVehic if no solid mask data at this position OR another solidmask was already present during put
BYTE *pSolidMaskMatBuff; // material replaced by this solidmask. MCVehic if no solid mask data at this position OR another solidmask was already present during put (independent of MaskMaterial)
BYTE MaskMaterial; // Either MCVehicle or MCHalfVehicle
C4Object *pForObject;
@ -86,6 +88,8 @@ public:
static void PutSolidMasks();
static CSurface8 *LoadMaskFromFile(class C4Group &hGroup, const char *szFilename);
void SetHalfVehicle(bool set);
};
#endif

View File

@ -152,10 +152,10 @@ void C4Object::TargetBounds(C4Real &ctco, int32_t limit_low, int32_t limit_hi, i
}
}
int32_t C4Object::ContactCheck(int32_t iAtX, int32_t iAtY, uint32_t *border_hack_contacts)
int32_t C4Object::ContactCheck(int32_t iAtX, int32_t iAtY, uint32_t *border_hack_contacts, bool collide_halfvehic)
{
// Check shape contact at given position
Shape.ContactCheck(iAtX,iAtY,border_hack_contacts);
Shape.ContactCheck(iAtX,iAtY,border_hack_contacts,collide_halfvehic);
// Store shape contact values in object t_contact
t_contact=Shape.ContactCNAT;
@ -281,7 +281,7 @@ void C4Object::DoMovement()
{
// Next step
int step = Sign(new_y - fix_y);
if ((iContact=ContactCheck(GetX(), GetY() + step)))
if ((iContact=ContactCheck(GetX(), GetY() + step, nullptr, ydir > 0)))
{
fAnyContact=true; iContacts |= t_contact;
new_y = fix_y;

View File

@ -2602,6 +2602,12 @@ void C4Object::SetSolidMask(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt,
if (CheckSolidMaskRect()) UpdateSolidMask(false);
}
void C4Object::SetHalfVehicleSolidMask(bool set)
{
if (!pSolidMaskData) return;
pSolidMaskData->SetHalfVehicle(set);
}
bool C4Object::CheckSolidMaskRect()
{
// Ensure SolidMask rect lies within bounds of SolidMask bitmap in definition

View File

@ -212,6 +212,7 @@ public:
void UpdateActionFace();
void SyncClearance();
void SetSolidMask(int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iTX, int32_t iTY);
void SetHalfVehicleSolidMask(bool set);
bool CheckSolidMaskRect(); // clip bounds of SolidMask in graphics - return whether the solidmask still exists
C4Object *ComposeContents(C4ID id);
bool MenuCommand(const char *szCommand);
@ -269,7 +270,7 @@ public:
void GetOCFForPos(int32_t ctx, int32_t cty, DWORD &ocf) const;
bool CloseMenu(bool fForce);
bool ActivateMenu(int32_t iMenu, int32_t iMenuSelect=0, int32_t iMenuData=0, int32_t iMenuPosition=0, C4Object *pTarget=NULL);
int32_t ContactCheck(int32_t atx, int32_t aty, uint32_t *border_hack_contacts=0);
int32_t ContactCheck(int32_t atx, int32_t aty, uint32_t *border_hack_contacts=0, bool collide_halfvehic=false);
bool Contact(int32_t cnat);
void TargetBounds(C4Real &ctco, int32_t limit_low, int32_t limit_hi, int32_t cnat_low, int32_t cnat_hi);
enum { SAC_StartCall = 1, SAC_EndCall = 2, SAC_AbortCall = 4 };

View File

@ -46,6 +46,12 @@ static C4Void FnSetSolidMask(C4Object *Obj, long iX, long iY, long iWdt, long iH
return C4Void();
}
static C4Void FnSetHalfVehicleSolidMask(C4Object *Obj, bool set)
{
Obj->SetHalfVehicleSolidMask(set);
return C4Void();
}
static C4Void FnDeathAnnounce(C4Object *Obj)
{
const long MaxDeathMsg=7;
@ -2498,6 +2504,7 @@ C4ScriptConstDef C4ScriptObjectConstMap[]=
{ "CNAT_Center" ,C4V_Int, CNAT_Center },
{ "CNAT_MultiAttach" ,C4V_Int, CNAT_MultiAttach },
{ "CNAT_NoCollision" ,C4V_Int, CNAT_NoCollision },
{ "CNAT_CollideHalfVehicle" ,C4V_Int, CNAT_CollideHalfVehicle },
// vertex data
{ "VTX_X" ,C4V_Int, VTX_X },
@ -2711,6 +2718,7 @@ void InitObjectFunctionMap(C4AulScriptEngine *pEngine)
AddFunc(pEngine, "Enter", FnEnter);
AddFunc(pEngine, "DeathAnnounce", FnDeathAnnounce);
AddFunc(pEngine, "SetSolidMask", FnSetSolidMask);
AddFunc(pEngine, "SetHalfVehicleSolidMask", FnSetHalfVehicleSolidMask);
AddFunc(pEngine, "Exit", FnExit);
AddFunc(pEngine, "Collect", FnCollect);
AddFunc(pEngine, "DoNoCollectDelay", FnDoNoCollectDelay);

View File

@ -187,6 +187,11 @@ void C4Shape::GetVertexOutline(C4Rect &rRect)
}
inline bool C4Shape::CheckTouchableMaterial(int32_t x, int32_t y, int32_t vtx_i, int32_t ydir, const C4DensityProvider &rDensityProvider) {
return rDensityProvider.GetDensity(x,y) >= ContactDensity &&
((ydir > 0 && (CNAT_CollideHalfVehicle & VtxCNAT[vtx_i])) || !IsMCHalfVehicle(GBackPix(x,y)));
}
// Adjust given position to one pixel before contact
// at vertices matching CNAT request.
bool C4Shape::Attach(int32_t &cx, int32_t &cy, BYTE cnat_pos)
@ -219,13 +224,13 @@ bool C4Shape::Attach(int32_t &cx, int32_t &cy, BYTE cnat_pos)
{
// get new vertex pos
int32_t ax = testx + VtxX[i], ay = testy + VtxY[i];
if (GBackDensity(ax, ay) >= ContactDensity)
if (CheckTouchableMaterial(ax, ay, i))
{
found = false;
break;
}
// can attach here?
if (GBackDensity(ax + xcd, ay + ycd) >= ContactDensity)
if (CheckTouchableMaterial(ax + xcd, ay + ycd, i, ycd))
{
found = true;
any_contact = true;
@ -348,14 +353,14 @@ bool C4Shape::CheckContact(int32_t cx, int32_t cy)
for (int32_t cvtx=0; cvtx<VtxNum; cvtx++)
if (!(VtxCNAT[cvtx] & CNAT_NoCollision))
if (GBackDensity(cx+VtxX[cvtx],cy+VtxY[cvtx]) >= ContactDensity)
if (CheckTouchableMaterial(cx+VtxX[cvtx],cy+VtxY[cvtx], cvtx))
return true;
return false;
}
bool C4Shape::ContactCheck(int32_t cx, int32_t cy, uint32_t *border_hack_contacts)
bool C4Shape::ContactCheck(int32_t cx, int32_t cy, uint32_t *border_hack_contacts, bool collide_halfvehic)
{
// Check all vertices at given object position.
// Set ContactCNAT and ContactCount.
@ -377,25 +382,25 @@ bool C4Shape::ContactCheck(int32_t cx, int32_t cy, uint32_t *border_hack_contact
int32_t y = cy+VtxY[cvtx];
VtxContactMat[cvtx]=GBackMat(x,y);
if (GBackDensity(x,y) >= ContactDensity)
if (CheckTouchableMaterial(x, y, cvtx, collide_halfvehic? 1:0))
{
ContactCNAT |= VtxCNAT[cvtx];
VtxContactCNAT[cvtx]|=CNAT_Center;
ContactCount++;
// Vertex center contact, now check top,bottom,left,right
if (GBackDensity(x,y-1) >= ContactDensity)
if (CheckTouchableMaterial(x,y-1,cvtx))
VtxContactCNAT[cvtx]|=CNAT_Top;
if (GBackDensity(x,y+1) >= ContactDensity)
if (CheckTouchableMaterial(x,y+1,cvtx))
VtxContactCNAT[cvtx]|=CNAT_Bottom;
if (GBackDensity(x-1,y) >= ContactDensity)
if (CheckTouchableMaterial(x-1,y,cvtx))
VtxContactCNAT[cvtx]|=CNAT_Left;
if (GBackDensity(x+1,y) >= ContactDensity)
if (CheckTouchableMaterial(x+1,y,cvtx))
VtxContactCNAT[cvtx]|=CNAT_Right;
}
if (border_hack_contacts)
{
if (x == 0 && GBackDensity(x-1, y) >= ContactDensity) *border_hack_contacts |= CNAT_Left;
else if (x == ::Landscape.Width && GBackDensity(x+1, y) >= ContactDensity) *border_hack_contacts |= CNAT_Right;
if (x == 0 && CheckTouchableMaterial(x-1, y, cvtx)) *border_hack_contacts |= CNAT_Left;
else if (x == ::Landscape.Width && CheckTouchableMaterial(x+1, y, cvtx)) *border_hack_contacts |= CNAT_Right;
}
}
@ -412,15 +417,15 @@ bool C4Shape::CheckScaleToWalk(int x, int y)
if (VtxCNAT[i] & CNAT_Bottom)
{
// no ground under the feet?
if (GBackDensity(x + VtxX[i], y + VtxY[i] + 1) < ContactDensity)
if (CheckTouchableMaterial(x + VtxX[i], y + VtxY[i] + 1, i))
return false;
}
else
{
// can climb with hands?
if (GBackDensity(x + VtxX[i] - 1, y + VtxY[i]) >= ContactDensity)
if (CheckTouchableMaterial(x + VtxX[i] - 1, y + VtxY[i], i))
return false;
if (GBackDensity(x + VtxX[i] + 1, y + VtxY[i]) >= ContactDensity)
if (CheckTouchableMaterial(x + VtxX[i] + 1, y + VtxY[i], i))
return false;
}
}
@ -504,11 +509,11 @@ int32_t C4Shape::GetVertexContact(int32_t iVtx, DWORD dwCheckMask, int32_t tx, i
// check all directions for solid mat
if (~VtxCNAT[iVtx] & CNAT_NoCollision)
{
if (dwCheckMask & CNAT_Center) if (rDensityProvider.GetDensity(tx, ty) >= ContactDensity) iContact |= CNAT_Center;
if (dwCheckMask & CNAT_Left) if (rDensityProvider.GetDensity(tx-1, ty) >= ContactDensity) iContact |= CNAT_Left;
if (dwCheckMask & CNAT_Right) if (rDensityProvider.GetDensity(tx+1, ty) >= ContactDensity) iContact |= CNAT_Right;
if (dwCheckMask & CNAT_Top) if (rDensityProvider.GetDensity(tx, ty-1) >= ContactDensity) iContact |= CNAT_Top;
if (dwCheckMask & CNAT_Bottom) if (rDensityProvider.GetDensity(tx, ty+1) >= ContactDensity) iContact |= CNAT_Bottom;
if (dwCheckMask & CNAT_Center) if (CheckTouchableMaterial(tx, ty , iVtx, 0, rDensityProvider)) iContact |= CNAT_Center;
if (dwCheckMask & CNAT_Left) if (CheckTouchableMaterial(tx-1, ty, iVtx, 0, rDensityProvider)) iContact |= CNAT_Left;
if (dwCheckMask & CNAT_Right) if (CheckTouchableMaterial(tx+1, ty, iVtx, 0, rDensityProvider)) iContact |= CNAT_Right;
if (dwCheckMask & CNAT_Top) if (CheckTouchableMaterial(tx, ty-1, iVtx, 0, rDensityProvider)) iContact |= CNAT_Top;
if (dwCheckMask & CNAT_Bottom) if (CheckTouchableMaterial(tx, ty+1, iVtx, 1, rDensityProvider)) iContact |= CNAT_Bottom;
}
// return resulting bitmask
return iContact;
@ -539,6 +544,7 @@ void C4Shape::CompileFunc(StdCompiler *pComp, const C4Shape *default_shape)
{ "CNAT_Center", CNAT_Center },
{ "CNAT_MultiAttach", CNAT_MultiAttach },
{ "CNAT_NoCollision", CNAT_NoCollision },
{ "CNAT_CollideHalfVehicle", CNAT_CollideHalfVehicle },
{ NULL, 0 }
};

View File

@ -68,7 +68,7 @@ public:
int32_t GetY() const { return y; }
bool AddVertex(int32_t iX, int32_t iY);
bool CheckContact(int32_t cx, int32_t cy);
bool ContactCheck(int32_t cx, int32_t cy, uint32_t *border_hack_contacts=0);
bool ContactCheck(int32_t cx, int32_t cy, uint32_t *border_hack_contacts=0, bool collide_halfvehic=false);
bool Attach(int32_t &cx, int32_t &cy, BYTE cnat_pos);
bool LineConnect(int32_t tx, int32_t ty, int32_t cvtx, int32_t ld, int32_t oldx, int32_t oldy);
bool InsertVertex(int32_t iPos, int32_t tx, int32_t ty);
@ -80,6 +80,8 @@ public:
bool CheckScaleToWalk(int x, int y);
void CreateOwnOriginalCopy(C4Shape &rFrom); // create copy of all vertex members in back area of own buffers
void CompileFunc(StdCompiler *pComp, const C4Shape *default_shape);
private:
bool CheckTouchableMaterial(int32_t x, int32_t y, int32_t vtx_i, int32_t y_dir = 0, const C4DensityProvider &rDensityProvider = DefaultDensityProvider);
};
#endif // INC_C4Shape