Esempio n. 1
0
bool ObjectComJump(C4Object *cObj) // by ObjectComUp, ExecCMDFMoveTo, FnJump
{
    // Only if walking
    if (cObj->GetProcedure()!=DFA_WALK) return false;
    // Calculate direction & forces
    C4Real TXDir=Fix0;
    C4PropList *pActionWalk = cObj->GetAction();
    C4Real iPhysicalWalk = C4REAL100(pActionWalk->GetPropertyInt(P_Speed)) * itofix(cObj->GetCon(), FullCon);
    C4Real iPhysicalJump = C4REAL100(cObj->GetPropertyInt(P_JumpSpeed)) * itofix(cObj->GetCon(), FullCon);

    if (cObj->Action.ComDir==COMD_Left || cObj->Action.ComDir==COMD_UpLeft)  TXDir=-iPhysicalWalk;
    else if (cObj->Action.ComDir==COMD_Right || cObj->Action.ComDir==COMD_UpRight) TXDir=+iPhysicalWalk;
    C4Real x = cObj->fix_x, y = cObj->fix_y;
    // find bottom-most vertex, correct starting position for simulation
    int32_t iBtmVtx = cObj->Shape.GetBottomVertex();
    if (iBtmVtx != -1) {
        x += cObj->Shape.GetVertexX(iBtmVtx);
        y += cObj->Shape.GetVertexY(iBtmVtx);
    }
    // Try dive
    if (cObj->Shape.ContactDensity > C4M_Liquid)
        if (SimFlightHitsLiquid(x,y,TXDir,-iPhysicalJump))
            if (ObjectActionDive(cObj,TXDir,-iPhysicalJump))
                return true;
    // Regular jump
    return ObjectActionJump(cObj,TXDir,-iPhysicalJump,true);
}
Esempio n. 2
0
C4Value C4Effect::DoCall(C4Object *pObj, const char *szFn, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4, const C4Value &rVal5, const C4Value &rVal6, const C4Value &rVal7)
{
	// def script or global only?
	C4PropList *p = GetCallbackScript();
	// compose function name
	char fn[C4AUL_MAX_Identifier+1];
	sprintf(fn, PSF_FxCustom, GetName(), szFn);
	return p->Call(fn, &C4AulParSet(C4VObj(pObj), C4VPropList(this), rVal1, rVal2, rVal3, rVal4, rVal5, rVal6, rVal7));
}
Esempio n. 3
0
void C4Effect::AssignCallbackFunctions()
{
	C4PropList *p = GetCallbackScript();
	// compose function names and search them
	char fn[C4AUL_MAX_Identifier+1];
	sprintf(fn, PSF_FxStart,  GetName()); pFnStart  = p->GetFunc(fn);
	sprintf(fn, PSF_FxStop,   GetName()); pFnStop   = p->GetFunc(fn);
	sprintf(fn, PSF_FxTimer,  GetName()); pFnTimer  = p->GetFunc(fn);
	sprintf(fn, PSF_FxEffect, GetName()); pFnEffect = p->GetFunc(fn);
	sprintf(fn, PSF_FxDamage, GetName()); pFnDamage = p->GetFunc(fn);
}
Esempio n. 4
0
void C4ScriptHost::UnLink()
{
	C4PropList * p = GetPropList();
	if (p)
	{
		p->C4PropList::Clear();
		p->SetProperty(P_Prototype, C4VPropList(Engine->GetPropList()));
	}

	// includes will have to be re-resolved now
	IncludesResolved = false;

	if (State > ASS_PREPARSED) State = ASS_PREPARSED;
}
Esempio n. 5
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. 6
0
bool C4PropList::operator==(const C4PropList &b) const
{
	// every numbered proplist has a unique number and is only identical to itself
	if (this == &b) return true;
	if (IsNumbered() || b.IsNumbered()) return false;
	if (Properties.GetSize() != b.Properties.GetSize()) return false;
	if (GetDef() != b.GetDef()) return false;
	const C4Property * p = Properties.First();
	while (p)
	{
		const C4Property & bp = b.Properties.Get(p->Key);
		if (!bp) return false;
		if (p->Value != bp.Value) return false;
		p = Properties.Next(p);
	}
	return true;
}
Esempio n. 7
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. 8
0
C4Value C4Effect::DoCall(C4PropList *pObj, const char *szFn, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4, const C4Value &rVal5, const C4Value &rVal6, const C4Value &rVal7)
{
	C4PropList * p = GetCallbackScript();
	if (!p)
	{
		C4AulFunc * fn = GetFunc(szFn);
		if (fn) return fn->Exec(this, &C4AulParSet(rVal1, rVal2, rVal3, rVal4, rVal5, rVal6, rVal7));
	}
	else
	{
		// old variant
		// compose function name
		C4AulFunc * fn = p->GetFunc(FormatString(PSF_FxCustom, GetName(), szFn).getData());
		if (fn) return fn->Exec(p, &C4AulParSet(Obj(pObj), this, rVal1, rVal2, rVal3, rVal4, rVal5, rVal6, rVal7));
	}
	return C4Value();
}
Esempio n. 9
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. 10
0
bool C4ValueProviderAction::Execute()
{
	// Object might have been removed
	if(!Object) return false;

	const C4Action& Action = Object->Action;
	C4PropList* pActionDef = Object->GetAction();

	// TODO: We could cache these...
	const StdMeshAnimation* animation = Action.Animation->GetAnimation();
	const int32_t length = pActionDef->GetPropertyInt(P_Length);
	const int32_t delay = pActionDef->GetPropertyInt(P_Delay);

	if (delay)
		Value = itofix(Action.Phase * delay + Action.PhaseDelay) * ftofix(animation->Length) / (delay * length);
	else
		Value = itofix(Action.Phase) * ftofix(animation->Length) / length;

	return true;
}
Esempio n. 11
0
void C4PropList::SetPropertyByS(C4String * k, const C4Value & to)
{
	assert(!constant);
	if (k == &Strings.P[P_Prototype])
	{
		C4PropList * newpt = to.getPropList();
		for(C4PropList * it = newpt; it; it = it->GetPrototype())
			if(it == this)
				throw C4AulExecError("Trying to create cyclic prototype structure");
		prototype.SetPropList(newpt);
	}
	else if (Properties.Has(k))
	{
		Properties.Get(k).Value = to;
	}
	else
	{
		Properties.Add(C4Property(k, to));
	}
}
Esempio n. 12
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. 13
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. 14
0
void C4AulScriptEngine::Clear()
{
#ifndef NOAULDEBUG
	// stop debugger
	delete C4AulDebug::GetDebugger();
#endif
	while (Child0)
		if (Child0->Delete()) delete Child0;
		else Child0->Unreg();
	// clear own stuff
	C4PropListStaticMember::Clear();
	// reset values
	warnCnt = errCnt = lineCnt = 0;
	// resetting name lists will reset all data lists, too
	// except not...
	GlobalNamedNames.Reset();
	GlobalConstNames.Reset();
	GlobalConsts.Reset();
	GlobalConsts.SetNameList(&GlobalConstNames);
	RegisterGlobalConstant("Global", C4VPropList(this));
	GlobalNamed.Reset();
	GlobalNamed.SetNameList(&GlobalNamedNames);
	delete pGlobalEffects; pGlobalEffects=nullptr;
	UserFiles.clear();
	// Delete all global proplists made static (breaks
	// cyclic references).
	for (C4Value& value: OwnedPropLists)
	{
		C4PropList* plist = value.getPropList();
		if (plist)
		{
			if (plist->Delete()) delete plist;
			else plist->Clear();
		}
	}
	OwnedPropLists.clear();
}
void C4GraphicsOverlay::UpdateFacet()
{
	// special: Nothing to update for object and pSourceGfx may be NULL
	// If there will ever be something to init here, UpdateFacet() will also need to be called when objects have been loaded
	if (eMode == MODE_Object) return;
	// otherwise, source graphics must be specified
	if (!pSourceGfx) return;
	C4Def *pDef = pSourceGfx->pDef;
	assert(pDef);
	fZoomToShape = false;
	// Clear old mesh instance, if any
	delete pMeshInstance; pMeshInstance = NULL;
	// update by mode
	switch (eMode)
	{
	case MODE_None:
		break;

	case MODE_Base: // def base graphics
		if (pSourceGfx->Type == C4DefGraphics::TYPE_Bitmap)
			fctBlit.Set(pSourceGfx->GetBitmap(), 0, 0, pDef->Shape.Wdt, pDef->Shape.Hgt, pDef->Shape.x+pDef->Shape.Wdt/2, pDef->Shape.y+pDef->Shape.Hgt/2);
		else if (pSourceGfx->Type == C4DefGraphics::TYPE_Mesh)
			pMeshInstance = new StdMeshInstance(*pSourceGfx->Mesh, 1.0f);
		break;

	case MODE_Action: // graphics of specified action
	{
		// Clear old facet
		fctBlit.Default();

		// Ensure there is actually an action set
		if (!Action[0])
			return;

		C4Value v;
		pDef->GetProperty(P_ActMap, &v);
		C4PropList *actmap = v.getPropList();
		if (!actmap)
			return;

		actmap->GetPropertyByS(::Strings.RegString(Action), &v);
		C4PropList *action = v.getPropList();
		if (!action)
			return;

		if (pSourceGfx->Type == C4DefGraphics::TYPE_Bitmap)
		{
			fctBlit.Set(pSourceGfx->GetBitmap(),
			            action->GetPropertyInt(P_X), action->GetPropertyInt(P_Y),
			            action->GetPropertyInt(P_Wdt), action->GetPropertyInt(P_Hgt));
			// FIXME: fctBlit.TargetX has to be set here
		}
		else if (pSourceGfx->Type == C4DefGraphics::TYPE_Mesh)
		{
			C4String* AnimationName = action->GetPropertyStr(P_Animation);
			if (!AnimationName) return;

			pMeshInstance = new StdMeshInstance(*pSourceGfx->Mesh, 1.0f);
			const StdMeshAnimation* Animation = pSourceGfx->Mesh->GetSkeleton().GetAnimationByName(AnimationName->GetData());
			if (!Animation) return;

			pMeshInstance->PlayAnimation(*Animation, 0, NULL, new C4ValueProviderRef<int32_t>(iPhase, ftofix(Animation->Length / action->GetPropertyInt(P_Length))), new C4ValueProviderConst(itofix(1)), true);
		}

		break;
	}
	case MODE_ObjectPicture: // ingame picture of object
		// calculated at runtime
		break;

	case MODE_IngamePicture:
	case MODE_Picture: // def picture
		fZoomToShape = true;
		// drawn at runtime
		break;

	case MODE_ExtraGraphics: // like ColorByOwner-sfc
		// calculated at runtime
		break;

	case MODE_Rank:
		// drawn at runtime
		break;

	case MODE_Object:
		// TODO
		break;
	}
}
Esempio n. 16
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;
}
Esempio n. 17
0
void C4Object::DoMovement()
{
	int32_t iContact=0;
	bool fAnyContact=false; int iContacts = 0;
	BYTE fTurned=0,fRedirectYR=0,fNoAttach=0;
	// Restrictions
	if (Def->NoHorizontalMove) xdir=0;
	// Dig free target area
	C4PropList* pActionDef = GetAction();
	if (pActionDef)
		if (pActionDef->GetPropertyInt(P_DigFree))
		{
			int ctcox, ctcoy;
			// Shape size square
			if (pActionDef->GetPropertyInt(P_DigFree)==1)
			{
				ctcox=fixtoi(fix_x+xdir); ctcoy=fixtoi(fix_y+ydir);
				::Landscape.DigFreeRect(ctcox+Shape.GetX(),ctcoy+Shape.GetY(),Shape.Wdt,Shape.Hgt,this);
			}
			// Free size round (variable size)
			else
			{
				ctcox=fixtoi(fix_x+xdir); ctcoy=fixtoi(fix_y+ydir);
				int32_t rad = pActionDef->GetPropertyInt(P_DigFree);
				if (Con<FullCon) rad = rad*6*Con/5/FullCon;
				::Landscape.DigFree(ctcox,ctcoy-1,rad,this);
			}
		}

	// store previous movement and ocf
	C4Real oldxdir(xdir), oldydir(ydir);
	uint32_t old_ocf = OCF;

	bool fMoved = false;
	C4Real new_x = fix_x + xdir;
	C4Real new_y = fix_y + ydir;
	SideBounds(new_x);

	if (!Action.t_attach) // Unattached movement  = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
	{
		// Horizontal movement - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		// Move to target
		while (fixtoi(new_x) != fixtoi(fix_x))
		{
			// Next step
			int step = Sign(new_x - fix_x);
			uint32_t border_hack_contacts = 0;
			iContact=ContactCheck(GetX() + step, GetY(), &border_hack_contacts);
			if (iContact || border_hack_contacts)
			{
				fAnyContact=true; iContacts |= t_contact | border_hack_contacts;
			}
			if (iContact)
			{
				// Abort horizontal movement
				new_x = fix_x;
				// Vertical redirection (always)
				RedirectForce(xdir,ydir,-1);
				ApplyFriction(ydir,ContactVtxFriction(this));
			}
			else // Free horizontal movement
			{
				DoMotion(step, 0);
				fMoved = true;
			}
		}
		// Vertical movement - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		// Movement target
		new_y = fix_y + ydir;
		// Movement bounds (vertical)
		VerticalBounds(new_y);
		// Move to target
		while (fixtoi(new_y) != fixtoi(fix_y))
		{
			// Next step
			int step = Sign(new_y - fix_y);
			if ((iContact=ContactCheck(GetX(), GetY() + step, nullptr, ydir > 0)))
			{
				fAnyContact=true; iContacts |= t_contact;
				new_y = fix_y;
				// Vertical contact horizontal friction
				ApplyFriction(xdir,ContactVtxFriction(this));
				// Redirection slide or rotate
				if (!ContactVtxCNAT(this,CNAT_Left))
					RedirectForce(ydir,xdir,-1);
				else if (!ContactVtxCNAT(this,CNAT_Right))
					RedirectForce(ydir,xdir,+1);
				else
				{
					// living things are always capable of keeping their rotation
					if (OCF & OCF_Rotate) if (iContact==1) if (!Alive)
							{
								RedirectForce(ydir,rdir,-ContactVtxWeight(this));
								fRedirectYR=1;
							}
					ydir=0;
				}
			}
			else // Free vertical movement
			{
				DoMotion(0,step);
				fMoved = true;
			}
		}
	}
	if (Action.t_attach) // Attached movement = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
	{
		VerticalBounds(new_y);
		// Move to target
		do
		{
			// Set next step target
			int step_x = 0, step_y = 0;
			if (fixtoi(new_x) != GetX())
				step_x = Sign(fixtoi(new_x) - GetX());
			else if (fixtoi(new_y) != GetY())
				step_y = Sign(fixtoi(new_y) - GetY());
			int32_t ctx = GetX() + step_x;
			int32_t cty = GetY() + step_y;
			// Attachment check
			if (!Shape.Attach(ctx,cty,Action.t_attach))
				fNoAttach=1;
			else
			{
				// Attachment change to ctx/cty overrides target
				if (ctx != GetX() + step_x)
				{
					xdir = Fix0; new_x = itofix(ctx);
				}
				if (cty != GetY() + step_y)
				{
					ydir = Fix0; new_y = itofix(cty);
				}
			}
			// Contact check & evaluation
			uint32_t border_hack_contacts = 0;
			iContact=ContactCheck(ctx,cty,&border_hack_contacts);
			if (iContact || border_hack_contacts)
			{
				fAnyContact=true; iContacts |= border_hack_contacts | t_contact;
			}
			if (iContact)
			{
				// Abort movement
				if (ctx != GetX())
				{
					ctx = GetX(); new_x = fix_x;
				}
				if (cty != GetY())
				{
					cty = GetY(); new_y = fix_y;
				}
			}
			DoMotion(ctx - GetX(), cty - GetY());
			fMoved = true;
		}
		while (fixtoi(new_x) != GetX() || fixtoi(new_y) != GetY());
	}

	if(fix_x != new_x || fix_y != new_y)
	{
		fMoved = true;
		if (pSolidMaskData) pSolidMaskData->Remove(true);
		fix_x = new_x;
		fix_y = new_y;
	}
	// Rotation  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	if (OCF & OCF_Rotate && !!rdir)
	{
		C4Real target_r = fix_r + rdir * 5;
		// Rotation limit
		if (Def->Rotateable>1)
		{
			if (target_r > itofix(Def->Rotateable))
				{ target_r = itofix(Def->Rotateable); rdir=0; }
			if (target_r < itofix(-Def->Rotateable))
				{ target_r = itofix(-Def->Rotateable); rdir=0; }
		}
		int32_t ctx=GetX(); int32_t cty=GetY();
		// Move to target
		while (fixtoi(fix_r) != fixtoi(target_r))
		{
			// Save step undos
			C4Real lcobjr = fix_r; C4Shape lshape=Shape;
			// Try next step
			fix_r += Sign(target_r - fix_r);
			UpdateShape();
			// attached rotation: rotate around attachment pos
			if (Action.t_attach && !fNoAttach)
			{
				// more accurately, attachment should be evaluated by a rotation around the attachment vertex
				// however, as long as this code is only used for some surfaces adjustment for large vehicles,
				// it's enough to assume rotation around the center
				ctx=GetX(); cty=GetY();
				// evaluate attachment, but do not bother about attachment loss
				// that will then be done in next execution cycle
				Shape.Attach(ctx,cty,Action.t_attach);
			}
			// check for contact
			if ((iContact=ContactCheck(ctx,cty))) // Contact
			{
				fAnyContact=true; iContacts |= t_contact;
				// Undo step and abort movement
				Shape=lshape;
				target_r = fix_r = lcobjr;
				// last UpdateShape-call might have changed sector lists!
				UpdatePos();
				// Redirect to GetY()
				if (iContact==1) if (!fRedirectYR)
						RedirectForce(rdir,ydir,-1);
				// Stop rotation
				rdir=0;
			}
			else
			{
				fTurned=1;
				if (ctx != GetX() || cty != GetY())
				{
					fix_x = itofix(ctx); fix_y = itofix(cty);
				}
			}
		}
		// Circle bounds
		if (target_r < -FixHalfCircle) { target_r += FixFullCircle; }
		if (target_r > +FixHalfCircle) { target_r -= FixFullCircle; }
		fix_r = target_r;
	}
	// Reput solid mask if moved by motion
	if (fMoved || fTurned) UpdateSolidMask(true);
	// Misc checks ===========================================================================================
	// InLiquid check
	// this equals C4Object::UpdateLiquid, but the "fNoAttach=false;"-line
	if (IsInLiquidCheck()) // In Liquid
	{
		if (!InLiquid) // Enter liquid
		{
			if (OCF & OCF_HitSpeed2) if (Mass>3)
					Splash(GetX(),GetY()+1,std::min(Shape.Wdt*Shape.Hgt/10,20),this);
			fNoAttach=false;
			InLiquid=1;
		}
	}
	else // Out of liquid
	{
		if (InLiquid) // Leave liquid
			InLiquid=0;
	}
	// Contact Action
	if (fAnyContact)
	{
		t_contact = iContacts;
		ContactAction();
	}
	// Attachment Loss Action
	if (fNoAttach)
		NoAttachAction();
	// Movement Script Execution
	if (fAnyContact)
	{
		C4AulParSet pars(C4VInt(fixtoi(oldxdir, 100)), C4VInt(fixtoi(oldydir, 100)));
		if (old_ocf & OCF_HitSpeed1) Call(PSF_Hit, &pars);
		if (old_ocf & OCF_HitSpeed2) Call(PSF_Hit2, &pars);
		if (old_ocf & OCF_HitSpeed3) Call(PSF_Hit3, &pars);
	}
	// Rotation gfx
	if (fTurned)
		UpdateFace(true);
	else
		// pos changed?
		if (fMoved) UpdatePos();
}
Esempio n. 18
0
C4PropListStatic * C4GameScriptHost::GetPropList()
{
	C4PropList * p = ScenPrototype._getPropList();
	return p ? p->IsStatic() : 0;
}
Esempio n. 19
0
C4AulDebug::ProcessLineResult C4AulDebug::ProcessLine(const StdStrBuf &Line)
{
	// Get command
	StdStrBuf Cmd;
	Cmd.CopyUntil(Line.getData(), ' ');
	// Get data
	const char *szData = Line.getPtr(Cmd.getLength());
	if (*szData) szData++;
	// Identify command
	const char *szCmd = Cmd.getData();
	if (SEqualNoCase(szCmd, "HELP"))
		return ProcessLineResult(false, "Yeah, like I'm going to explain that /here/");
	else if (SEqualNoCase(szCmd, "BYE") || SEqualNoCase(szCmd, "QUIT"))
		C4NetIOTCP::Close(PeerAddr);
	else if (SEqualNoCase(szCmd, "SAY"))
		::Control.DoInput(CID_Message, new C4ControlMessage(C4CMT_Normal, szData), CDT_Direct);
	else if (SEqualNoCase(szCmd, "CMD"))
		::MessageInput.ProcessCommand(szData);
	else if (SEqualNoCase(szCmd, "STP") || SEqualNoCase(szCmd, "S"))
		eState = DS_Step;
	else if (SEqualNoCase(szCmd, "GO") || SEqualNoCase(szCmd, "G"))
		eState = DS_Go;
	else if (SEqualNoCase(szCmd, "STO") || SEqualNoCase(szCmd, "O"))
		eState = DS_StepOver;
	else if (SEqualNoCase(szCmd, "STR") || SEqualNoCase(szCmd, "R"))
		eState = DS_StepOut;
	else if (SEqualNoCase(szCmd, "EXC") || SEqualNoCase(szCmd, "E"))
	{
		C4AulScriptContext* context = pExec->GetContext(pExec->GetContextDepth()-1);
		int32_t objectNum = C4ControlScript::SCOPE_Global;
		if (context && context->Obj && context->Obj->GetObject())
			objectNum = context->Obj->GetObject()->Number;
		::Control.DoInput(CID_Script, new C4ControlScript(szData, objectNum, true), CDT_Decide);
	}
	else if (SEqualNoCase(szCmd, "PSE"))
		if (Game.IsPaused())
		{
			Game.Unpause();
			return ProcessLineResult(true, "Game unpaused.");
		}
		else
		{
			Game.Pause();
			return ProcessLineResult(true, "Game paused.");
		}
	else if (SEqualNoCase(szCmd, "LST"))
	{
		for (C4AulScript* script = ScriptEngine.Child0; script; script = script->Next)
		{
			SendLine(RelativePath(script->ScriptName));
		}
	}

	// toggle breakpoint
	else if (SEqualNoCase(szCmd, "TBR"))
	{
		using namespace std;
		// FIXME: this doesn't find functions which were included/appended
		string scriptPath = szData;
		size_t colonPos = scriptPath.find(':');
		if (colonPos == string::npos)
			return ProcessLineResult(false, "Missing line in breakpoint request");
		int line = atoi(&scriptPath[colonPos+1]);
		scriptPath.erase(colonPos);

		C4AulScript *script;
		for (script = ScriptEngine.Child0; script; script = script->Next)
		{
			if (SEqualNoCase(RelativePath(script->ScriptName), scriptPath.c_str()))
				break;
		}

		auto sh = script ? script->GetScriptHost() : NULL;
		if (sh)
		{
			C4AulBCC * found = NULL;
			for (auto script = ::ScriptEngine.Child0; script; script = script->Next)
			for (C4PropList *props = script->GetPropList(); props; props = props->GetPrototype())
			for (auto fname = props->EnumerateOwnFuncs(); fname; fname = props->EnumerateOwnFuncs(fname))
			{
				C4Value val;
				if (!props->GetPropertyByS(fname, &val)) continue;
				auto func = val.getFunction();
				if (!func) continue;
				auto sfunc = func->SFunc();
				if (!sfunc) continue;
				if (sfunc->pOrgScript != sh) continue;
				for (auto chunk = sfunc->GetCode(); chunk->bccType != AB_EOFN; chunk++)
				{
					if (chunk->bccType == AB_DEBUG)
					{
						int lineOfThisOne = sfunc->GetLineOfCode(chunk);
						if (lineOfThisOne == line)
						{
							found = chunk;
							goto Found;
						}
					}
				}
			}
			Found:
			if (found)
				found->Par.i = !found->Par.i; // activate breakpoint
			else
				return ProcessLineResult(false, "Can't set breakpoint (wrong line?)");
		}
		else
			return ProcessLineResult(false, "Can't find script");
	}
	else if (SEqualNoCase(szCmd, "SST"))
	{
		std::list<StdStrBuf*>::iterator it = StackTrace.begin();
		for (it++; it != StackTrace.end(); it++)
		{
			SendLine("AT", (*it)->getData());
		}
		SendLine("EST");
	}
	else if (SEqualNoCase(szCmd, "VAR"))
	{
		
		C4Value *val = NULL;
		int varIndex;
		C4AulScriptContext* pCtx = pExec->GetContext(pExec->GetContextDepth() - 1);
		if (pCtx)
		{
			if ((varIndex = pCtx->Func->ParNamed.GetItemNr(szData)) != -1)
			{
				val = &pCtx->Pars[varIndex];
			}
			else if ((varIndex = pCtx->Func->VarNamed.GetItemNr(szData)) != -1)
			{
				val = &pCtx->Vars[varIndex];
			}
		}
		const char* typeName = val ? GetC4VName(val->GetType()) : "any";
		StdStrBuf output = FormatString("%s %s %s", szData, typeName, val ? val->GetDataString().getData() : "Unknown");
		SendLine("VAR", output.getData());
	}
	else
		return ProcessLineResult(false, "Can't do that");
	
	return ProcessLineResult(true, "");
}
Esempio n. 20
0
float C4SoundModifier::GetFloatProp(C4PropertyName key, float ratio, float default_value)
{
    // get scaled property and fill in default value
    C4PropList *p = props._getPropList();
    return float(p->GetPropertyInt(key, int32_t(default_value * ratio))) / ratio;
}
Esempio n. 21
0
bool C4SoundModifier::GetBoolProp(C4PropertyName key, bool default_value)
{
    // get scaled property and fill in default value
    C4PropList *p = props._getPropList();
    return (p->GetPropertyInt(key, int32_t(default_value ? 1 : 0)) != 0);
}