Esempio n. 1
0
void C4Object::SideBounds(C4Real &ctcox)
{
	// layer bounds
	if (Layer) if (Layer->Def->BorderBound & C4D_Border_Layer)
		{
			C4PropList* pActionDef = GetAction();
			if (!pActionDef || pActionDef->GetPropertyP(P_Procedure) != DFA_ATTACH)
			{
				TargetBounds(ctcox, Layer->GetX() + Layer->Shape.GetX() - Shape.GetX(), Layer->GetX() + Layer->Shape.GetX() + Layer->Shape.Wdt + Shape.GetX(), CNAT_Left, CNAT_Right);
			}
		}
	// landscape bounds
	if (Def->BorderBound & C4D_Border_Sides)
		TargetBounds(ctcox,0-Shape.GetX(),GBackWdt+Shape.GetX(),CNAT_Left,CNAT_Right);
}
Esempio n. 2
0
void C4Object::VerticalBounds(C4Real &ctcoy)
{
	// layer bounds
	if (Layer) if (Layer->Def->BorderBound & C4D_Border_Layer)
		{
			C4PropList* pActionDef = GetAction();
			if (!pActionDef || pActionDef->GetPropertyP(P_Procedure) != DFA_ATTACH)
			{
				TargetBounds(ctcoy, Layer->GetY() + Layer->Shape.GetY() - Shape.GetY(), Layer->GetY() + Layer->Shape.GetY() + Layer->Shape.Hgt + Shape.GetY(), CNAT_Top, CNAT_Bottom);
			}
		}
	// landscape bounds
	if (Def->BorderBound & C4D_Border_Top)
		TargetBounds(ctcoy,0-Shape.GetY(),+1000000,CNAT_Top,CNAT_Bottom);
	if (Def->BorderBound & C4D_Border_Bottom)
		TargetBounds(ctcoy,-1000000,GBackHgt+Shape.GetY(),CNAT_Top,CNAT_Bottom);
}
Esempio n. 3
0
bool ObjectComDrop(C4Object *cObj, C4Object *pThing)
{
    // No object specified, first from contents
    if (!pThing) pThing = cObj->Contents.GetObject();
    // Nothing to throw
    if (!pThing) return false;
    // Force and direction
    // When dropping diagonally, drop from edge of shape
    // When doing a diagonal forward drop during flight, exit a bit closer to the Clonk to allow planned tumbling
    // Except when hangling, so you can mine effectively form the ceiling, and when swimming because you cannot tumble then
    C4Real pthrow=C4REAL100(cObj->GetPropertyInt(P_ThrowSpeed));
    int32_t tdir=0;
    int right=0;
    bool isHanglingOrSwimming = false;
    int32_t iProc = -1;
    C4PropList* pActionDef = cObj->GetAction();
    if (pActionDef)
    {
        iProc = pActionDef->GetPropertyP(P_Procedure);
        if (iProc == DFA_HANGLE || iProc == DFA_SWIM) isHanglingOrSwimming = true;
    }
    int32_t iOutposReduction = 1; // don't exit object too far forward during jump
    if (iProc != DFA_SCALE) // never diagonal during scaling (can have com into wall during scaling!)
    {
        if (ComDirLike(cObj->Action.ComDir, COMD_Left)) {
            tdir=-1;
            right = 0;
            if (cObj->xdir < C4REAL10(15) && !isHanglingOrSwimming) --iOutposReduction;
        }
        if (ComDirLike(cObj->Action.ComDir, COMD_Right)) {
            tdir=+1;
            right = 1;
            if (cObj->xdir > C4REAL10(-15) && !isHanglingOrSwimming) --iOutposReduction;
        }
    }
    // Exit object
    pThing->Exit(cObj->GetX() + (cObj->Shape.x + cObj->Shape.Wdt * right) * !!tdir * iOutposReduction,
                 cObj->GetY()+cObj->Shape.y+cObj->Shape.Hgt-(pThing->Shape.y+pThing->Shape.Hgt),0,pthrow*tdir,Fix0,Fix0);
    // Update OCF
    cObj->SetOCF();
    // Ungrab
    ObjectComUnGrab(cObj);
    // Done
    return true;
}
Esempio n. 4
0
void C4Object::VerticalBounds(C4Real &ctcoy)
{
	// layer bounds
	if (Layer && Layer->GetPropertyInt(P_BorderBound) & C4D_Border_Layer)
	{
		C4PropList* pActionDef = GetAction();
		if (!pActionDef || pActionDef->GetPropertyP(P_Procedure) != DFA_ATTACH)
		{
			C4Real tbound = itofix(Layer->GetY() + Layer->Shape.GetY() - Shape.GetY()),
			       bbound = itofix(Layer->GetY() + Layer->Shape.GetY() + Layer->Shape.Hgt - (Shape.GetY() + Shape.Hgt));
			if (ctcoy < tbound) StopAndContact(ctcoy, tbound, ydir, CNAT_Top);
			if (ctcoy > bbound) StopAndContact(ctcoy, bbound, ydir, CNAT_Bottom);
		}
	}
	// landscape bounds
	C4Real tbound = itofix(0 - Shape.GetY()),
	       bbound = itofix(GBackHgt - (Shape.GetY() + Shape.Hgt));
	if (ctcoy < tbound && GetPropertyInt(P_BorderBound) & C4D_Border_Top)
		StopAndContact(ctcoy, tbound, ydir, CNAT_Top);
	if (ctcoy > bbound && GetPropertyInt(P_BorderBound) & C4D_Border_Bottom)
		StopAndContact(ctcoy, bbound, ydir, CNAT_Bottom);
}
Esempio n. 5
0
// Stop the object and do contact calls if it collides with the border
void C4Object::SideBounds(C4Real &ctcox)
{
	// layer bounds
	if (Layer && Layer->GetPropertyInt(P_BorderBound) & C4D_Border_Layer)
	{
		C4PropList* pActionDef = GetAction();
		if (!pActionDef || pActionDef->GetPropertyP(P_Procedure) != DFA_ATTACH)
		{
			C4Real lbound = itofix(Layer->GetX() + Layer->Shape.GetX() - Shape.GetX()),
			       rbound = itofix(Layer->GetX() + Layer->Shape.GetX() + Layer->Shape.Wdt - (Shape.GetX() + Shape.Wdt));
			if (ctcox < lbound) StopAndContact(ctcox, lbound, xdir, CNAT_Left);
			if (ctcox > rbound) StopAndContact(ctcox, rbound, xdir, CNAT_Right);
		}
	}
	// landscape bounds
	C4Real lbound = itofix(0 - Shape.GetX()),
	       rbound = itofix(GBackWdt - (Shape.GetX() + Shape.Wdt));
	if (ctcox < lbound && GetPropertyInt(P_BorderBound) & C4D_Border_Sides)
		StopAndContact(ctcox, lbound, xdir, CNAT_Left);
	if (ctcox > rbound && GetPropertyInt(P_BorderBound) & C4D_Border_Sides)
		StopAndContact(ctcox, rbound, xdir, CNAT_Right);
}
Esempio n. 6
0
bool C4Object::ExecMovement() // Every Tick1 by Execute
{
	// update in which material this object is
	UpdateInMat();

	// Containment check
	if (Contained)
	{
		CopyMotion(Contained);

		return true;
	}

	// General mobility check
	if (Category & C4D_StaticBack) return false;

	// Movement execution
	if (Mobile) // Object is moving
	{
		// Move object
		DoMovement();
		// Demobilization check
		if ((xdir==0) && (ydir==0) && (rdir==0)) Mobile=0;
		// Check for stabilization
		if (rdir==0) Stabilize();
	}
	else // Object is static
	{
		// Check for stabilization
		Stabilize();
		// Check for mobilization
		if (!::Game.iTick10)
		{
			// Gravity mobilization
			xdir=ydir=rdir=0;
			Mobile=1;
		}
	}

	// Enforce zero rotation
	if (!Def->Rotateable) fix_r=Fix0;

	// Out of bounds check
	if ((!Inside<int32_t>(GetX() + Shape.GetX(), -Shape.Wdt, GBackWdt) && !(GetPropertyInt(P_BorderBound) & C4D_Border_Sides))
	    || ((GetY() + Shape.GetY() > GBackHgt) && !(GetPropertyInt(P_BorderBound) & C4D_Border_Bottom)))
	{
		C4PropList* pActionDef = GetAction();
		// Never remove attached objects: If they are truly outside landscape, their target will be removed,
		//  and the attached objects follow one frame later
		if (!pActionDef || !Action.Target || pActionDef->GetPropertyP(P_Procedure) != DFA_ATTACH)
		{
			bool fRemove = true;
			// never remove HUD objects
			if (Category & C4D_Parallax)
			{
				int parX, parY;
				GetParallaxity(&parX, &parY);
				fRemove = false;
				if (GetX()>GBackWdt || GetY()>GBackHgt) fRemove = true; // except if they are really out of the viewport to the right...
				else if (GetX()<0 && !!parX) fRemove = true; // ...or it's not HUD horizontally and it's out to the left
				else if (!parX && GetX()<-GBackWdt) fRemove = true; // ...or it's HUD horizontally and it's out to the left
			}
			if (fRemove)
			{
				AssignDeath(true);
				AssignRemoval();
			}
		}
	}
	return true;
}