コード例 #1
0
ファイル: C4Effect.cpp プロジェクト: lluchs/clonk-rage
void C4Effect::Kill(C4Object *pObj) {
  // active?
  C4Effect *pLastRemovedEffect = NULL;
  if (IsActive())
    // then temp remove all higher priority effects
    TempRemoveUpperEffects(pObj, false, &pLastRemovedEffect);
  else
      // otherwise: temp reactivate before real removal
      // this happens only if a lower priority effect removes an upper priority
      // effect in its add- or removal-call
      if (pFnStart && iPriority != 1)
    pFnStart->Exec(pCommandTarget,
                   &C4AulParSet(C4VObj(pObj), C4VInt(iNumber),
                                C4VInt(C4FxCall_TempAddForRemoval)));
  // remove this effect
  int32_t iPrevPrio = iPriority;
  SetDead();
  if (pFnStop)
    if (pFnStop->Exec(pCommandTarget,
                      &C4AulParSet(C4VObj(pObj), C4VInt(iNumber))).getInt() ==
        C4Fx_Stop_Deny)
      // effect denied to be removed: recover
      iPriority = iPrevPrio;
  // reactivate other effects
  TempReaddUpperEffects(pObj, pLastRemovedEffect);
}
コード例 #2
0
bool C4Object::Exit(int32_t iX, int32_t iY, int32_t iR, C4Real iXDir, C4Real iYDir, C4Real iRDir, bool fCalls)
{
	// 1. Exit the current container.
	// 2. Update Contents of container object and set Contained to nullptr.
	// 3. Set offset position/motion if desired.
	// 4. Call Ejection for container and Departure for object.

	// Not contained
	C4Object *pContainer=Contained;
	if (!pContainer) return false;
	// Remove object from container
	pContainer->Contents.Remove(this);
	pContainer->UpdateMass();
	pContainer->SetOCF();
	// No container
	Contained=nullptr;
	// Position/motion
	fix_x=itofix(iX); fix_y=itofix(iY);
	fix_r=itofix(iR);
	BoundsCheck(fix_x, fix_y);
	xdir=iXDir; ydir=iYDir; rdir=iRDir;
	// Misc updates
	Mobile=true;
	InLiquid=false;
	CloseMenu(true);
	UpdateFace(true);
	SetOCF();
	// Object list callback (before script callbacks, because script callbacks may enter again)
	ObjectListChangeListener.OnObjectContainerChanged(this, pContainer, nullptr);
	// Engine calls
	if (fCalls) pContainer->Call(PSF_Ejection,&C4AulParSet(this));
	if (fCalls) Call(PSF_Departure,&C4AulParSet(pContainer));
	// Success (if the obj wasn't "re-entered" by script)
	return !Contained;
}
コード例 #3
0
ファイル: C4ObjectCom.cpp プロジェクト: lluchs/clonk-rage
BOOL ObjectComPunch(C4Object *cObj, C4Object *pTarget, int32_t punch)
  {
  if (!cObj || !pTarget) return FALSE;
	if (!punch)
		if (pTarget->GetPhysical()->Fight) 
			punch=BoundBy<int32_t>(5*cObj->GetPhysical()->Fight/pTarget->GetPhysical()->Fight,0,10);
	if (!punch) return TRUE;
	bool fBlowStopped = !!pTarget->Call(PSF_QueryCatchBlow,&C4AulParSet(C4VObj(cObj)));
	if (fBlowStopped && punch>1) punch=punch/2; // half damage for caught blow, so shield+armor help in fistfight and vs monsters
	pTarget->DoEnergy(-punch, false, C4FxCall_EngGetPunched, cObj->Controller);
  int32_t tdir=+1; if (cObj->Action.Dir==DIR_Left) tdir=-1;
  pTarget->Action.ComDir=COMD_Stop;
	// No tumbles when blow was caught
	if (fBlowStopped) return FALSE;
	// Hard punch
	if (punch>=10) 
		if (ObjectActionTumble(pTarget,pTarget->Action.Dir,FIXED100(150)*tdir,itofix(-2)))
			{
			pTarget->LastEnergyLossCausePlayer = cObj->Controller; // for kill tracing when pushing enemies off a cliff
			pTarget->Call(PSF_CatchBlow,&C4AulParSet(C4VInt(punch), C4VObj(cObj)));
			return TRUE;
			}

	// Regular punch
	if (ObjectActionGetPunched(pTarget,FIXED100(250)*tdir,Fix0))
		{
		pTarget->LastEnergyLossCausePlayer = cObj->Controller; // for kill tracing when pushing enemies off a cliff
		pTarget->Call(PSF_CatchBlow,&C4AulParSet(C4VInt(punch), C4VObj(cObj))); 
		return TRUE;
		}

	return FALSE;
  }
コード例 #4
0
ファイル: C4ObjectCom.cpp プロジェクト: Fulgen301/openclonk
bool ObjectComPunch(C4Object *cObj, C4Object *pTarget, int32_t punch)
{
	if (!cObj || !pTarget) return false;
	if (!punch) return true;
	bool fBlowStopped = !!pTarget->Call(PSF_QueryCatchBlow,&C4AulParSet(cObj));
	if (fBlowStopped && punch>1) punch=punch/2; // half damage for caught blow, so shield+armor help in fistfight and vs monsters
	pTarget->DoEnergy(-punch, false, C4FxCall_EngGetPunched, cObj->Controller);
	int32_t tdir=+1; if (cObj->Action.Dir==DIR_Left) tdir=-1;
	pTarget->Action.ComDir=COMD_Stop;
	// No tumbles when blow was caught
	if (fBlowStopped) return false;
	// Hard punch
	if (punch>=10)
		if (ObjectActionTumble(pTarget,pTarget->Action.Dir,C4REAL100(150)*tdir,itofix(-2)))
		{
			pTarget->Call(PSF_CatchBlow,&C4AulParSet(punch, cObj));
			return true;
		}

	// Regular punch
	if (ObjectActionGetPunched(pTarget,C4REAL100(250)*tdir,Fix0))
	{
		pTarget->Call(PSF_CatchBlow,&C4AulParSet(punch, cObj));
		return true;
	}

	return false;
}
コード例 #5
0
int C4Effect::CallTimer(int time)
{
	if (!GetCallbackScript())
		return Call(P_Timer, &C4AulParSet(time)).getInt();
	if (pFnTimer)
		return pFnTimer->Exec(GetCallbackScript(), &C4AulParSet(Obj(Target), this, time)).getInt();
	return C4Fx_Execute_Kill;
}
コード例 #6
0
int C4Effect::CallStop(int reason, bool temporary)
{
	if (!GetCallbackScript())
		return Call(P_Stop, &C4AulParSet(reason, temporary)).getInt();
	if (pFnStop)
		return pFnStop->Exec(GetCallbackScript(), &C4AulParSet(Obj(Target), this, reason, temporary)).getInt();
	return C4Fx_OK;
}
コード例 #7
0
int C4Effect::CallStart(int temporary, const C4Value &var1, const C4Value &var2, const C4Value &var3, const C4Value &var4)
{
	if (!GetCallbackScript())
		return Call(P_Start, &C4AulParSet(temporary, var1, var2, var3, var4)).getInt();
	if (pFnStart)
		return pFnStart->Exec(GetCallbackScript(), &C4AulParSet(Obj(Target), this, temporary, var1, var2, var3, var4)).getInt();
	return C4Fx_OK;
}
コード例 #8
0
int C4Effect::CallEffect(const char * effect, const C4Value &var1, const C4Value &var2, const C4Value &var3, const C4Value &var4)
{
	if (!GetCallbackScript())
		return Call(P_Effect, &C4AulParSet(effect, var1, var2, var3, var4)).getInt();
	if (pFnEffect)
		return pFnEffect->Exec(GetCallbackScript(), &C4AulParSet(effect, Obj(Target), this, var1, var2, var3, var4)).getInt();
	return C4Fx_OK;
}
コード例 #9
0
ファイル: C4ObjectCom.cpp プロジェクト: Fulgen301/openclonk
bool ObjectComGrab(C4Object *cObj, C4Object *pTarget)
{
	if (!pTarget) return false;
	if (cObj->GetProcedure()!=DFA_WALK) return false;
	if (!ObjectActionPush(cObj,pTarget)) return false;
	cObj->Call(PSF_Grab, &C4AulParSet(pTarget, true));
	if (pTarget->Status && cObj->Status)
		pTarget->Call(PSF_Grabbed, &C4AulParSet(cObj, true));
	return true;
}
コード例 #10
0
void C4Effect::CallDamage(int32_t & damage, int damagetype, int plr)
{
	if (!GetCallbackScript())
	{
		C4AulFunc *pFn = GetFunc(P_Damage);
		if (pFn)
			damage = pFn->Exec(this, &C4AulParSet(damage, damagetype, plr)).getInt();
	}
	else if (pFnDamage)
		damage = pFnDamage->Exec(GetCallbackScript(), &C4AulParSet(Obj(Target), this, damage, damagetype, plr)).getInt();
}
コード例 #11
0
ファイル: C4ObjectCom.cpp プロジェクト: lluchs/clonk-rage
BOOL ObjectComGrab(C4Object *cObj, C4Object *pTarget)
	{
	if (!pTarget) return FALSE;
	if (cObj->GetProcedure()!=DFA_WALK) return FALSE;
	if (!ObjectActionPush(cObj,pTarget)) return FALSE;
	cObj->Call(PSF_Grab, &C4AulParSet(C4VObj(pTarget), C4VBool(true)));
	if (pTarget->Status && cObj->Status)
	{
		pTarget->Controller = cObj->Controller;
		pTarget->Call(PSF_Grabbed, &C4AulParSet(C4VObj(cObj), C4VBool(true)));
	}
	return TRUE;
	}
コード例 #12
0
ファイル: C4Def.cpp プロジェクト: farad91/openclonk
int32_t C4Def::GetValue(C4Object *pInBase, int32_t iBuyPlayer)
{
	C4Value r = Call(PSF_CalcDefValue, &C4AulParSet(pInBase, iBuyPlayer));
	int32_t iValue = Value;
	if (r != C4VNull)
		iValue = r.getInt();
	// do any adjustments based on where the item is bought
	if (pInBase)
	{
		r = pInBase->Call(PSF_CalcBuyValue, &C4AulParSet(this, iValue));
		if (r != C4VNull)
			iValue = r.getInt();
	}
	return iValue;
}
コード例 #13
0
void C4Effect::Kill()
{
	// active?
	C4Effect *pLastRemovedEffect=NULL;
	if (IsActive())
		// then temp remove all higher priority effects
		TempRemoveUpperEffects(false, &pLastRemovedEffect);
	else
		// otherwise: temp reactivate before real removal
		// this happens only if a lower priority effect removes an upper priority effect in its add- or removal-call
		if (iPriority!=1) CallStart(C4FxCall_TempAddForRemoval, C4Value(), C4Value(), C4Value(), C4Value());
	// remove this effect
	int32_t iPrevPrio = iPriority; SetDead();
	if (CallStop(C4FxCall_Normal, false) == C4Fx_Stop_Deny)
		// effect denied to be removed: recover
		iPriority = iPrevPrio;
	// reactivate other effects
	TempReaddUpperEffects(pLastRemovedEffect);
	// Update OnFire cache
	if (Target && WildcardMatch(C4Fx_AnyFire, GetName()))
		if (!Get(C4Fx_AnyFire))
			Target->SetOnFire(false);
	if (IsDead() && !GetCallbackScript())
		Call(P_Destruction, &C4AulParSet(C4FxCall_Normal));
}
コード例 #14
0
ファイル: C4Effect.cpp プロジェクト: lluchs/clonk-rage
C4Value C4Effect::DoCall(C4Object *pObj, const char *szFn, C4Value &rVal1,
                         C4Value &rVal2, C4Value &rVal3, C4Value &rVal4,
                         C4Value &rVal5, C4Value &rVal6, C4Value &rVal7) {
  // def script or global only?
  C4AulScript *pSrcScript;
  C4Def *pDef;
  if (pCommandTarget) {
    pSrcScript = &pCommandTarget->Def->Script;
    // overwrite ID for sync safety in runtime join
    idCommandTarget = pCommandTarget->id;
  } else if (idCommandTarget && (pDef = Game.Defs.ID2Def(idCommandTarget)))
    pSrcScript = &pDef->Script;
  else
    pSrcScript = &Game.ScriptEngine;
  // compose function name
  char fn[C4AUL_MAX_Identifier + 1];
  sprintf(fn, PSF_FxCustom, Name, szFn);
  // call it
  C4AulFunc *pFn = pSrcScript->GetFuncRecursive(fn);
  if (!pFn)
    return C4Value();
  return pFn->Exec(pCommandTarget,
                   &C4AulParSet(C4VObj(pObj), C4VInt(iNumber), rVal1, rVal2,
                                rVal3, rVal4, rVal5, rVal6, rVal7));
}
コード例 #15
0
ファイル: C4Effect.cpp プロジェクト: lluchs/clonk-rage
void C4Effect::TempRemoveUpperEffects(C4Object *pObj, bool fTempRemoveThis,
                                      C4Effect **ppLastRemovedEffect) {
  if (pObj && !pObj->Status)
    return; // this will be invalid!
  // priority=1: no callbacks
  if (iPriority == 1)
    return;
  // remove from high to low priority
  // recursive implementation...
  C4Effect *pEff = pNext;
  while (pEff)
    if (pEff->IsActive())
      break;
    else
      pEff = pEff->pNext;
  // temp remove active effects with higher priority
  if (pEff)
    pEff->TempRemoveUpperEffects(pObj, true, ppLastRemovedEffect);
  // temp remove this
  if (fTempRemoveThis) {
    FlipActive();
    // temp callbacks only for higher priority effects
    if (pFnStop && iPriority != 1)
      pFnStop->Exec(pCommandTarget,
                    &C4AulParSet(C4VObj(pObj), C4VInt(iNumber),
                                 C4VInt(C4FxCall_Temp), C4VBool(true)));
    if (!*ppLastRemovedEffect)
      *ppLastRemovedEffect = this;
  }
}
コード例 #16
0
ファイル: C4ObjectCom.cpp プロジェクト: Fulgen301/openclonk
bool ObjectComPut(C4Object *cObj, C4Object *pTarget, C4Object *pThing)
{
	// No object specified, first from contents
	if (!pThing) pThing = cObj->Contents.GetObject();
	// Nothing to put
	if (!pThing) return false;
	// No target
	if (!pTarget) return false;
	// Grabbing: check C4D_Grab_Put
	if (pTarget!=cObj->Contained)
		if (!(pTarget->Def->GrabPutGet & C4D_Grab_Put))
		{
			// No grab put: fail
			return false;
		}
	// Target no fullcon
	if (!(pTarget->OCF & OCF_FullCon)) return false;
	// Transfer thing
	bool fRejectCollect;
	if (!pThing->Enter(pTarget, true, true, &fRejectCollect)) return false;
	// Put call to object script
	cObj->Call(PSF_Put);
	// Target collection call
	pTarget->Call(PSF_Collection,&C4AulParSet(pThing, true));
	// Success
	return true;
}
コード例 #17
0
ファイル: C4ObjectCom.cpp プロジェクト: lluchs/clonk-rage
BOOL ObjectComPut(C4Object *cObj, C4Object *pTarget, C4Object *pThing)
  {
  // No object specified, first from contents
	if (!pThing) pThing = cObj->Contents.GetObject();
	// Nothing to put
	if (!pThing) return FALSE;
	// No target
  if (!pTarget) return FALSE;
  // Grabbing: check C4D_Grab_Put
  if (pTarget!=cObj->Contained)
    if (!(pTarget->Def->GrabPutGet & C4D_Grab_Put)) 
      {
      // Was meant to be a drop anyway
      if (ValidPlr(cObj->Owner))
        if (Game.Players.Get(cObj->Owner)->LastComDownDouble)
          return ObjectComDrop(cObj, pThing);
      // No grab put: fail
      return FALSE;
      }
  // Target no fullcon
  if (!(pTarget->OCF & OCF_FullCon)) return FALSE;
	// Check target collection limit
	if (pTarget->Def->CollectionLimit && (pTarget->Contents.ObjectCount()>=pTarget->Def->CollectionLimit)) return FALSE;
  // Transfer thing
	bool fRejectCollect;
  if (!pThing->Enter(pTarget, TRUE, true, &fRejectCollect)) return FALSE;
	// Put call to object script
  cObj->Call(PSF_Put);
	// Target collection call
  pTarget->Call(PSF_Collection,&C4AulParSet(C4VObj(pThing), C4VBool(TRUE)));
	// Success
  return TRUE;
  }
コード例 #18
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();
}
コード例 #19
0
ファイル: C4Effect.cpp プロジェクト: 772/openclonk
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));
}
コード例 #20
0
ファイル: C4ObjectCom.cpp プロジェクト: lluchs/clonk-rage
BOOL ObjectComUnGrab(C4Object *cObj)
	{
	// Only if pushing, -> stand
	if (cObj->GetProcedure() == DFA_PUSH)
		{
		C4Object *pTarget = cObj->Action.Target;
		if (ObjectActionStand(cObj))
			{
			if (!cObj->CloseMenu(false)) return FALSE;
			cObj->Call(PSF_Grab, &C4AulParSet(C4VObj(pTarget), C4VBool(false)));
			if (pTarget && pTarget->Status && cObj->Status)
				pTarget->Call(PSF_Grabbed, &C4AulParSet(C4VObj(cObj), C4VBool(false)));
			return TRUE;
			}
		}

	return FALSE;
	}
コード例 #21
0
ファイル: C4ObjectCom.cpp プロジェクト: lluchs/clonk-rage
void ObjectComDigDouble(C4Object *cObj) // "Activation" by DFA_WALK, DFA_DIG, DFA_SWIM
  {  
	C4Object *pTarget;
  DWORD ocf;
  C4PhysicalInfo *phys=cObj->GetPhysical();

	// Contents activation (first contents object only)
	if (cObj->Contents.GetObject())
		if (!! cObj->Contents.GetObject()->Call(PSF_Activate,&C4AulParSet(C4VObj(cObj))))
			return;
  
	// Linekit: Line construction (move to linekit script...)
  if (cObj->Contents.GetObject() && (cObj->Contents.GetObject()->id==C4ID_Linekit)) 
    {
		ObjectComLineConstruction(cObj);
		return;
    }
  
	// Chop
  ocf=OCF_Chop;
  if (phys->CanChop)
		if (cObj->GetProcedure()!=DFA_SWIM)
	    if ((pTarget=Game.Objects.AtObject(cObj->x,cObj->y,ocf,cObj)))
		    if (ocf & OCF_Chop)
			    { 
				  PlayerObjectCommand(cObj->Owner,C4CMD_Chop,pTarget);
					return; 
					}

	// Line construction pick up
  ocf=OCF_LineConstruct;
  if (phys->CanConstruct)
	  if (!cObj->Contents.GetObject())
	    if ((pTarget=Game.Objects.AtObject(cObj->x,cObj->y,ocf,cObj)))
		    if (ocf & OCF_LineConstruct)
			    if (ObjectComLineConstruction(cObj))
						return; 

  // Own activation call
  if (!! cObj->Call(PSF_Activate, &C4AulParSet(C4VObj(cObj)))) return;
	 
  }
コード例 #22
0
ファイル: C4Effect.cpp プロジェクト: 772/openclonk
void C4Effect::DoDamage(C4Object *pObj, int32_t &riDamage, int32_t iDamageType, int32_t iCausePlr)
{
	// ask all effects for damage adjustments
	C4Effect *pEff = this;
	do
	{
		if (!pEff->IsDead() && pEff->pFnDamage)
			riDamage = pEff->pFnDamage->Exec(pEff->CommandTarget, &C4AulParSet(C4VObj(pObj), C4VPropList(pEff), C4VInt(riDamage), C4VInt(iDamageType), C4VInt(iCausePlr))).getInt();
		if (pObj && !pObj->Status) return;
	}
	while ((pEff = pEff->pNext) && riDamage);
}
コード例 #23
0
C4Effect * C4Effect::Init(C4PropList *pForObj, int32_t iPrio, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4)
{
	Target = pForObj;
	// ask all effects with higher priority first - except for prio 1 effects, which are considered out of the priority call chain (as per doc)
	bool fRemoveUpper = (iPrio != 1);
	// note that apart from denying the creation of this effect, higher priority effects may also remove themselves
	// or do other things with the effect list
	// (which does not quite make sense, because the effect might be denied by another effect)
	// so the priority is assigned after this call, marking this effect dead before it's definitely valid
	if (fRemoveUpper && pNext)
	{
		C4Effect * pEffect2 = pNext->Check(GetName(), iPrio, iInterval, rVal1, rVal2, rVal3, rVal4);
		if (pEffect2)
		{
			// effect denied (iResult = -1), added to an effect (iResult = Number of that effect)
			// or added to an effect that destroyed itself (iResult = -2)
			if (pEffect2 != (C4Effect*)C4Fx_Effect_Deny && pEffect2 != (C4Effect*)C4Fx_Effect_Annul) return pEffect2;
			// effect is still marked dead
			return 0;
		}
	}
	// init effect
	// higher-priority effects must be deactivated temporarily, and then reactivated regarding the new effect
	// higher-level effects should not be inserted during the process of removing or adding a lower-level effect
	// because that would cause a wrong initialization order
	// (hardly ever causing trouble, however...)
	C4Effect *pLastRemovedEffect=NULL;
	C4AulFunc * pFn;
	if (!GetCallbackScript())
	{
		Call(P_Construction, &C4AulParSet(rVal1, rVal2, rVal3, rVal4)).getInt();
		if (pForObj && !pForObj->Status) return 0;
		pFn = GetFunc(P_Start);
	}
	else
		pFn = pFnStart;
	if (fRemoveUpper && pNext && pFn)
		TempRemoveUpperEffects(false, &pLastRemovedEffect);
	// bad things may happen
	if (pForObj && !pForObj->Status) return 0; // this will be invalid!
	iPriority = iPrio; // validate effect now
	if (CallStart(0, rVal1, rVal2, rVal3, rVal4) == C4Fx_Start_Deny)
		// the effect denied to start: assume it hasn't, and mark it dead
		SetDead();
	if (fRemoveUpper && pNext && pFn)
		TempReaddUpperEffects(pLastRemovedEffect);
	if (pForObj && !pForObj->Status) return 0; // this will be invalid!
	// Update OnFire cache
	if (!IsDead() && pForObj && WildcardMatch(C4Fx_AnyFire, GetName()))
		pForObj->SetOnFire(true);
	return this;
}
コード例 #24
0
ファイル: C4Effect.cpp プロジェクト: lluchs/clonk-rage
int32_t C4Effect::Check(C4Object *pForObj, const char *szCheckEffect,
                        int32_t iPrio, int32_t iTimer, C4Value &rVal1,
                        C4Value &rVal2, C4Value &rVal3, C4Value &rVal4) {
  // priority=1: always OK; no callbacks
  if (iPrio == 1)
    return 0;
  // check this and other effects
  C4Effect *pAddToEffect = NULL;
  bool fDoTempCallsForAdd = false;
  C4Effect *pLastRemovedEffect = NULL;
  for (C4Effect *pCheck = this; pCheck; pCheck = pCheck->pNext) {
    if (!pCheck->IsDead() && pCheck->pFnEffect && pCheck->iPriority >= iPrio) {
      int32_t iResult =
          pCheck->pFnEffect->Exec(pCheck->pCommandTarget,
                                  &C4AulParSet(C4VString(szCheckEffect),
                                               C4VObj(pForObj),
                                               C4VInt(pCheck->iNumber),
                                               C4Value(), rVal1, rVal2, rVal3,
                                               rVal4)).getInt();
      if (iResult == C4Fx_Effect_Deny)
        // effect denied
        return C4Fx_Effect_Deny;
      // add to other effect
      if (iResult == C4Fx_Effect_Annul || iResult == C4Fx_Effect_AnnulCalls) {
        pAddToEffect = pCheck;
        fDoTempCallsForAdd = (iResult == C4Fx_Effect_AnnulCalls);
      }
    }
  }
  // adding to other effect?
  if (pAddToEffect) {
    // do temp remove calls if desired
    if (pAddToEffect->pNext && fDoTempCallsForAdd)
      pAddToEffect->TempRemoveUpperEffects(pForObj, false, &pLastRemovedEffect);
    C4Value Par1 = C4VString(szCheckEffect), Par2 = C4VInt(iTimer), Par8;
    int32_t iResult =
        pAddToEffect->DoCall(pForObj, PSFS_FxAdd, Par1, Par2, rVal1, rVal2,
                             rVal3, rVal4, Par8).getInt();
    // do temp readd calls if desired
    if (pAddToEffect->pNext && fDoTempCallsForAdd)
      pAddToEffect->TempReaddUpperEffects(pForObj, pLastRemovedEffect);
    // effect removed by this call?
    if (iResult == C4Fx_Start_Deny) {
      pAddToEffect->Kill(pForObj);
      return C4Fx_Effect_Annul;
    } else
      // other effect is the target effect number
      return pAddToEffect->iNumber;
  }
  // added to no effect and not denied
  return 0;
}
コード例 #25
0
void C4Object::DirectComContents(C4Object *pTarget, bool fDoCalls)
{
	// safety
	if (!pTarget || !pTarget->Status || pTarget->Contained != this) return;
	// Desired object already at front?
	if (Contents.GetObject() == pTarget) return;
	// select object via script?
	if (fDoCalls)
		if (Call("~ControlContents", &C4AulParSet(pTarget)))
			return;
	// default action
	if (!(Contents.ShiftContents(pTarget))) return;
	// Selection sound
	if (fDoCalls) if (!Contents.GetObject()->Call("~Selection", &C4AulParSet(this))) StartSoundEffect("Clonk::Action::Grab",false,100,this);
	// update menu with the new item in "put" entry
	if (Menu && Menu->IsActive() && Menu->IsContextMenu())
	{
		Menu->Refill();
	}
	// Done
	return;
}
コード例 #26
0
ファイル: C4ObjectCom.cpp プロジェクト: Fulgen301/openclonk
bool ObjectComUnGrab(C4Object *cObj)
{
	// Only if pushing, -> stand
	if (cObj->GetProcedure() == DFA_PUSH)
	{
		C4Object *pTarget = cObj->Action.Target;
		if (ObjectActionStand(cObj))
		{
			if (!cObj->CloseMenu(false)) return false;
			cObj->Call(PSF_Grab, &C4AulParSet(pTarget, false));
			// clear action target
			cObj->Action.Target = nullptr;
			if (pTarget && pTarget->Status && cObj->Status)
			{
				pTarget->Call(PSF_Grabbed, &C4AulParSet(cObj, false));
			}
			return true;
		}
	}

	return false;
}
コード例 #27
0
bool C4PlayerList::Remove(C4Player *pPlr, bool fDisconnect, bool fNoCalls)
{
	if (!pPlr) return false;

	// inform script
	if (!fNoCalls)
		::Game.GRBroadcast(PSF_RemovePlayer, &C4AulParSet(C4VInt(pPlr->Number), C4VInt(pPlr->Team)));

	// Transfer ownership of other objects to team members
	if (!fNoCalls) pPlr->NotifyOwnedObjects();

	// NET2: update player info list
	if (pPlr->ID)
	{
		C4PlayerInfo *pInfo = Game.PlayerInfos.GetPlayerInfoByID(pPlr->ID);
		if (pInfo)
		{
			pInfo->SetRemoved();
			if (fDisconnect)
				pInfo->SetDisconnected();
		}
		// if player wasn't evaluated, store round results anyway
		if (!pPlr->Evaluated) Game.RoundResults.EvaluatePlayer(pPlr);
	}

	C4Player *pPrev=First;
	while (pPrev && pPrev->Next!=pPlr) pPrev=pPrev->Next;
	if (pPrev) pPrev->Next=pPlr->Next;
	else First=pPlr->Next;

	// Remove eliminated crew
	if (!fNoCalls) pPlr->RemoveCrewObjects();

	// Clear object info pointers
	pPlr->CrewInfoList.DetachFromObjects();

	// Clear viewports
	::Viewports.CloseViewport(pPlr->Number, fNoCalls);
	// Check fullscreen viewports
	FullScreen.ViewportCheck();

	// Remove player
	delete pPlr;

	// Validate object owners
	::Objects.ValidateOwners();

	// Update console
	Console.UpdateMenus();
	return true;
}
コード例 #28
0
ファイル: C4Effect.cpp プロジェクト: 772/openclonk
void C4Effect::Kill(C4Object *pObj)
{
	// active?
	C4Effect *pLastRemovedEffect=NULL;
	if (IsActive())
		// then temp remove all higher priority effects
		TempRemoveUpperEffects(pObj, false, &pLastRemovedEffect);
	else
		// otherwise: temp reactivate before real removal
		// this happens only if a lower priority effect removes an upper priority effect in its add- or removal-call
		if (pFnStart && iPriority!=1) pFnStart->Exec(CommandTarget, &C4AulParSet(C4VObj(pObj), C4VPropList(this), C4VInt(C4FxCall_TempAddForRemoval)));
	// remove this effect
	int32_t iPrevPrio = iPriority; SetDead();
	if (pFnStop)
		if (pFnStop->Exec(CommandTarget, &C4AulParSet(C4VObj(pObj), C4VPropList(this), C4VInt(C4FxCall_Normal))).getInt() == C4Fx_Stop_Deny)
			// effect denied to be removed: recover
			iPriority = iPrevPrio;
	// reactivate other effects
	TempReaddUpperEffects(pObj, pLastRemovedEffect);
	// Update OnFire cache
	if (pObj && WildcardMatch(C4Fx_AnyFire, GetName()))
		if (!Get(C4Fx_AnyFire))
			pObj->SetOnFire(false);
}
コード例 #29
0
ファイル: C4Effect.cpp プロジェクト: 772/openclonk
void C4Effect::Execute(C4Object *pObj)
{
	// get effect list
	C4Effect **ppEffectList = pObj ? &pObj->pEffects : &Game.pGlobalEffects;
	// execute all effects not marked as dead
	C4Effect *pEffect = this, **ppPrevEffect=ppEffectList;
	do
	{
		// effect dead?
		if (pEffect->IsDead())
		{
			// delete it, then
			C4Effect *pNextEffect = pEffect->pNext;
			pEffect->pNext = NULL;
			delete pEffect;
			// next effect
			*ppPrevEffect = pEffect = pNextEffect;
		}
		else
		{
			// execute effect: time elapsed
			++pEffect->iTime;
			// check timer execution
			if (pEffect->iInterval && !(pEffect->iTime % pEffect->iInterval))
			{
				if (pEffect->pFnTimer)
				{
					if (pEffect->pFnTimer->Exec(pEffect->CommandTarget, &C4AulParSet(C4VObj(pObj), C4VPropList(pEffect), C4VInt(pEffect->iTime))).getInt() == C4Fx_Execute_Kill)
					{
						// safety: this class got deleted!
						if (pObj && !pObj->Status) return;
						// timer function decided to finish it
						pEffect->Kill(pObj);
					}
					// safety: this class got deleted!
					if (pObj && !pObj->Status) return;
				}
				else
					// no timer function: mark dead after time elapsed
					pEffect->Kill(pObj);
			}
			// next effect
			ppPrevEffect = &pEffect->pNext;
			pEffect = pEffect->pNext;
		}
	}
	while (pEffect);
}
コード例 #30
0
ファイル: C4Effect.cpp プロジェクト: 772/openclonk
C4Effect * C4Effect::New(C4Object * pForObj, C4String * szName, int32_t iPrio, int32_t iTimerInterval, C4Object * pCmdTarget, C4ID idCmdTarget, const C4Value &rVal1, const C4Value &rVal2, const C4Value &rVal3, const C4Value &rVal4)
{
	C4Effect * pEffect = new C4Effect(pForObj, szName, iPrio, iTimerInterval, pCmdTarget, idCmdTarget, rVal1, rVal2, rVal3, rVal4);
	// ask all effects with higher priority first - except for prio 1 effects, which are considered out of the priority call chain (as per doc)
	bool fRemoveUpper = (iPrio != 1);
	// note that apart from denying the creation of this effect, higher priority effects may also remove themselves
	// or do other things with the effect list
	// (which does not quite make sense, because the effect might be denied by another effect)
	// so the priority is assigned after this call, marking this effect dead before it's definitely valid
	if (fRemoveUpper && pEffect->pNext)
	{
		C4Effect * pEffect2 = pEffect->pNext->Check(pForObj, szName->GetCStr(), iPrio, iTimerInterval, rVal1, rVal2, rVal3, rVal4);
		if (pEffect2)
		{
			// effect denied (iResult = -1), added to an effect (iResult = Number of that effect)
			// or added to an effect that destroyed itself (iResult = -2)
			if (pEffect2 != (C4Effect*)C4Fx_Effect_Deny && pEffect2 != (C4Effect*)C4Fx_Effect_Annul) return pEffect2;
			// effect is still marked dead
			return 0;
		}
	}
	// init effect
	// higher-priority effects must be deactivated temporarily, and then reactivated regarding the new effect
	// higher-level effects should not be inserted during the process of removing or adding a lower-level effect
	// because that would cause a wrong initialization order
	// (hardly ever causing trouble, however...)
	C4Effect *pLastRemovedEffect=NULL;
	if (fRemoveUpper && pEffect->pNext && pEffect->pFnStart)
		pEffect->TempRemoveUpperEffects(pForObj, false, &pLastRemovedEffect);
	// bad things may happen
	if (pForObj && !pForObj->Status) return 0; // this will be invalid!
	pEffect->iPriority = iPrio; // validate effect now
	if (pEffect->pFnStart)
		if (pEffect->pFnStart->Exec(pCmdTarget, &C4AulParSet(C4VObj(pForObj), C4VPropList(pEffect), C4VInt(0), rVal1, rVal2, rVal3, rVal4)).getInt() == C4Fx_Start_Deny)
			// the effect denied to start: assume it hasn't, and mark it dead
			pEffect->SetDead();
	if (fRemoveUpper && pEffect->pNext && pEffect->pFnStart)
		pEffect->TempReaddUpperEffects(pForObj, pLastRemovedEffect);
	if (pForObj && !pForObj->Status) return 0; // this will be invalid!
	// Update OnFire cache
	if (!pEffect->IsDead() && pForObj && WildcardMatch(C4Fx_AnyFire, szName->GetCStr()))
		pForObj->SetOnFire(true);
	return pEffect;
}