forked from Mirrors/openclonk
Add a new variant of vehicle that can be passed from below but be walked on from above.
parent
05a78138a3
commit
2a9b481087
|
@ -0,0 +1,5 @@
|
|||
[Material]
|
||||
Name=HalfVehicle
|
||||
Density=100
|
||||
Friction=100
|
||||
KeepSinglePixels=1
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 =====================================================
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue