Пример #1
0
BOOL DETOUR_CGameSprite::DETOUR_EvaluateTrigger(Trigger& t) {
	if (0) IECString("DETOUR_CGameSprite::DETOUR_EvaluateTrigger");

	Trigger tTemp = t;
	CCreatureObject* pCre = NULL;
	CGameSprite* pSprite = NULL;
	Object oCriteria;
	int nFindTargetResult = 0;
	BOOL bResult = FALSE;

	switch (tTemp.m_wOpcode) {
	case TRIGGER_MOVEMENT_RATE:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		CAnimation* pAnim = pCre->m_animation.m_pAnimation;
		if (pAnim == NULL) break;
		unsigned char nMvt = pAnim->GetCurrentMovementRate();
		bResult = (signed int)nMvt == tTemp.m_i;
		}
		break;
	case TRIGGER_MOVEMENT_RATE_GT:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		CAnimation* pAnim = pCre->m_animation.m_pAnimation;
		if (pAnim == NULL) break;
		unsigned char nMvt = pAnim->GetCurrentMovementRate();
		bResult = (signed int)nMvt > tTemp.m_i;
		}
		break;
	case TRIGGER_MOVEMENT_RATE_LT:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		CAnimation* pAnim = pCre->m_animation.m_pAnimation;
		if (pAnim == NULL) break;
		unsigned char nMvt = pAnim->GetCurrentMovementRate();
		bResult = (signed int)nMvt < tTemp.m_i;
		}
		break;
	case TRIGGER_NUM_MIRRORIMAGES:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		unsigned char nImages = pCre->m_nMirrorImages;
		bResult = (signed int)nImages == tTemp.m_i;
		}
		break;
	case TRIGGER_NUM_MIRRORIMAGES_GT:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		unsigned char nImages = pCre->m_nMirrorImages;
		bResult = (signed int)nImages > tTemp.m_i;
		}
		break;
	case TRIGGER_NUM_MIRRORIMAGES_LT:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		unsigned char nImages = pCre->m_nMirrorImages;
		bResult = (signed int)nImages < tTemp.m_i;
		}
		break;
	case TRIGGER_BOUNCING_SPELL_LEVEL:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		if (tTemp.m_i < 0) break;
		if (tTemp.m_i > 9) break;
		bResult = pCre->GetDerivedStats().m_bBounceSplLvl[tTemp.m_i] || pCre->GetDerivedStats().m_BounceSplLvlDec[tTemp.m_i].m_bOn;
		}
		break;
	case TRIGGER_NUM_BOUNCING_SPELL_LEVEL:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		if (tTemp.m_i < 0) break;
		if (tTemp.m_i > 9) break;
		unsigned int nNumBounce = 0;
		if (pCre->GetDerivedStats().m_bBounceSplLvl[tTemp.m_i]) {
			nNumBounce = UINT_MAX;
		} else {
			if (pCre->GetDerivedStats().m_BounceSplLvlDec[tTemp.m_i].m_bOn)
				nNumBounce = pCre->GetDerivedStats().m_BounceSplLvlDec[tTemp.m_i].m_nCount;
		}
		bResult = nNumBounce == tTemp.m_i2;
		}
		break;
	case TRIGGER_NUM_BOUNCING_SPELL_LEVEL_GT:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		if (tTemp.m_i < 0) break;
		if (tTemp.m_i > 9) break;
		unsigned int nNumBounce = 0;
		if (pCre->GetDerivedStats().m_bBounceSplLvl[tTemp.m_i]) {
			nNumBounce = UINT_MAX;
		} else {
			if (pCre->GetDerivedStats().m_BounceSplLvlDec[tTemp.m_i].m_bOn)
				nNumBounce = pCre->GetDerivedStats().m_BounceSplLvlDec[tTemp.m_i].m_nCount;
		}
		bResult = nNumBounce > (unsigned int)tTemp.m_i2;
		}
		break;
	case TRIGGER_NUM_BOUNCING_SPELL_LEVEL_LT:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		if (tTemp.m_i < 0) break;
		if (tTemp.m_i > 9) break;
		unsigned int nNumBounce = 0;
		if (pCre->GetDerivedStats().m_bBounceSplLvl[tTemp.m_i]) {
			nNumBounce = UINT_MAX;
		} else {
			if (pCre->GetDerivedStats().m_BounceSplLvlDec[tTemp.m_i].m_bOn)
				nNumBounce = pCre->GetDerivedStats().m_BounceSplLvlDec[tTemp.m_i].m_nCount;
		}
		bResult = nNumBounce < (unsigned int)tTemp.m_i2;
		}
		break;
	case TRIGGER_IMMUNE_SPELL_LEVEL:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		if (tTemp.m_i < 0) break;
		if (tTemp.m_i > 9) break;
		bResult = pCre->GetDerivedStats().m_bProtSplLvl[tTemp.m_i] || pCre->GetDerivedStats().m_ProtSplLvlDec[tTemp.m_i].m_bOn;
		}
		break;
	case TRIGGER_NUM_IMMUNE_SPELL_LEVEL:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		if (tTemp.m_i < 0) break;
		if (tTemp.m_i > 9) break;
		unsigned int nNumProt = 0;
		if (pCre->GetDerivedStats().m_bProtSplLvl[tTemp.m_i]) {
			nNumProt = UINT_MAX;
		} else {
			if (pCre->GetDerivedStats().m_ProtSplLvlDec[tTemp.m_i].m_bOn)
				nNumProt = pCre->GetDerivedStats().m_ProtSplLvlDec[tTemp.m_i].m_nCount;
		}
		bResult = nNumProt == tTemp.m_i2;
		}
		break;
	case TRIGGER_NUM_IMMUNE_SPELL_LEVEL_GT:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		if (tTemp.m_i < 0) break;
		if (tTemp.m_i > 9) break;
		unsigned int nNumProt = 0;
		if (pCre->GetDerivedStats().m_bProtSplLvl[tTemp.m_i]) {
			nNumProt = UINT_MAX;
		} else {
			if (pCre->GetDerivedStats().m_ProtSplLvlDec[tTemp.m_i].m_bOn)
				nNumProt = pCre->GetDerivedStats().m_ProtSplLvlDec[tTemp.m_i].m_nCount;
		}
		bResult = nNumProt > (unsigned int)tTemp.m_i2;
		}
		break;
	case TRIGGER_NUM_IMMUNE_SPELL_LEVEL_LT:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		if (tTemp.m_i < 0) break;
		if (tTemp.m_i > 9) break;
		unsigned int nNumProt = 0;
		if (pCre->GetDerivedStats().m_bProtSplLvl[tTemp.m_i]) {
			nNumProt = UINT_MAX;
		} else {
			if (pCre->GetDerivedStats().m_ProtSplLvlDec[tTemp.m_i].m_bOn)
				nNumProt = pCre->GetDerivedStats().m_ProtSplLvlDec[tTemp.m_i].m_nCount;
		}
		bResult = nNumProt < (unsigned int)tTemp.m_i2;
		}
		break;
	case TRIGGER_TIME_STOP_COUNTER:
		bResult = g_pChitin->GetInfGame().m_nTimeStopObjectsTicksLeft == tTemp.m_i;
		break;
	case TRIGGER_TIME_STOP_COUNTER_GT:
		bResult = g_pChitin->GetInfGame().m_nTimeStopObjectsTicksLeft > tTemp.m_i;
		break;
	case TRIGGER_TIME_STOP_COUNTER_LT:
		bResult = g_pChitin->GetInfGame().m_nTimeStopObjectsTicksLeft < tTemp.m_i;
		break;
	case TRIGGER_TIME_STOP_OBJECT:
		tTemp.DecodeIdentifiers(*this);
		pSprite = (CGameSprite*)&tTemp.m_o.FindTargetOfType(*this, CGAMEOBJECT_TYPE_SPRITE, FALSE);
		if (pSprite == NULL) break;
		bResult = pSprite->m_e == g_pChitin->GetInfGame().m_eTimeStopExempt;
		break;
	case TRIGGER_NUM_TRAPPING_SPELL_LEVEL:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		if (tTemp.m_i < 0) break;
		if (tTemp.m_i > 9) break;
		unsigned int nNumTrap = 0;
		if (pCre->GetDerivedStats().m_SplTrapLvl[tTemp.m_i].m_bOn)
			nNumTrap = pCre->GetDerivedStats().m_SplTrapLvl[tTemp.m_i].m_nCount;
		bResult = nNumTrap == tTemp.m_i2;
		}
		break;
	case TRIGGER_NUM_TRAPPING_SPELL_LEVEL_GT:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		if (tTemp.m_i < 0) break;
		if (tTemp.m_i > 9) break;
		unsigned int nNumTrap = 0;
		if (pCre->GetDerivedStats().m_SplTrapLvl[tTemp.m_i].m_bOn)
			nNumTrap = pCre->GetDerivedStats().m_SplTrapLvl[tTemp.m_i].m_nCount;
		bResult = nNumTrap > (unsigned int)tTemp.m_i2;
		}
		break;
	case TRIGGER_NUM_TRAPPING_SPELL_LEVEL_LT:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		if (tTemp.m_i < 0) break;
		if (tTemp.m_i > 9) break;
		unsigned int nNumTrap = 0;
		if (pCre->GetDerivedStats().m_SplTrapLvl[tTemp.m_i].m_bOn)
			nNumTrap = pCre->GetDerivedStats().m_SplTrapLvl[tTemp.m_i].m_nCount;
		bResult = nNumTrap < (unsigned int)tTemp.m_i2;
		}
		break;
	case TRIGGER_ORIGINAL_CLASS:
		{
		tTemp.DecodeIdentifiers(*this);
		unsigned char nClassOld;
		unsigned char nClassNew;
		tTemp.m_o.GetDualClasses(&nClassNew, &nClassOld);
		if (nClassNew == nClassOld) break; //not dual-class
		oCriteria.m_cClass = tTemp.m_i;
		Object oTemp;
		oTemp.m_cClass = nClassOld;
		bResult = oTemp.MatchCriteria(oCriteria, FALSE, FALSE, FALSE);
		}
		break;
	case TRIGGER_HP_LOST:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		int nHurtAmount = pCre->m_cdsCurrent.m_wMaxHP - pCre->m_header.m_wHitPoints;
		bResult = nHurtAmount == tTemp.m_i;
		}
		break;
	case TRIGGER_HP_LOST_GT:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		int nHurtAmount = pCre->m_cdsCurrent.m_wMaxHP - pCre->m_header.m_wHitPoints;
		bResult = nHurtAmount > tTemp.m_i;
		}
		break;
	case TRIGGER_HP_LOST_LT:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		int nHurtAmount = pCre->m_cdsCurrent.m_wMaxHP - pCre->m_header.m_wHitPoints;
		bResult = nHurtAmount < tTemp.m_i;
		}
		break;
	case TRIGGER_EQUALS:
		bResult = tTemp.m_i == tTemp.m_i2;
		break;
	case TRIGGER_GT:
		bResult = tTemp.m_i > tTemp.m_i2;
		break;
	case TRIGGER_LT:
		bResult = tTemp.m_i < tTemp.m_i2;
		break;
	case TRIGGER_CHECK_STAT_BAND:
		{
		nFindTargetResult = FindTargetCreature(tTemp, &pCre);
		if (pCre == NULL) break;
		bResult = (BOOL)(pCre->GetDerivedStats().GetStat(tTemp.m_i2) & tTemp.m_i);
		break;
		}
	default:
		bResult = (this->*Tramp_CGameSprite_EvaluateTrigger)(t);
		break;
	}

	return bResult;

}
Пример #2
0
BOOL DETOUR_CScriptBlock::DETOUR_Evaluate(CTriggerList& triggers, CGameSprite& sprite) {
	if (0) IECString("DETOUR_CScriptBlock::DETOUR_Evaluate");

	//normal trigger variables
	BOOL bResult = FALSE;
	int nOr = 0;
	bool bBreak = false;
	
	//NextTriggerObject() variables
	BOOL bOverrideObject = FALSE;
	Object oOverride;
	CGameSprite* pOverrideSprite = NULL;

	//Eval() variables
	BOOL bOverrideInt[] = { FALSE, FALSE };
	int nOverride[] = { 0, 0 };
	BOOL bOverrideStr[] = { FALSE, FALSE };
	IECString sOverride[2];

	POSITION pos = m_lTriggers.GetHeadPosition();
	if (pos == NULL) return TRUE;

	while (pos != NULL && !bBreak) {
		if (nOr <= 0) bResult = FALSE; //AND
		Trigger* pt = (Trigger*)m_lTriggers.GetNext(pos);
		Trigger tCopy = *pt;
		
		switch (tCopy.m_wOpcode) {
		case TRIGGER_NEXT_TRIGGER_OBJECT:
			oOverride = tCopy.m_o;
			oOverride.DecodeIdentifiers(sprite);
			pOverrideSprite = (CGameSprite*)&oOverride.FindTargetOfType((CGameObject&)sprite, CGAMEOBJECT_TYPE_SPRITE, FALSE);
			bOverrideObject = TRUE;
			break;

		case TRIGGER_ASSIGN:
		{
			IECString sStatement = tCopy.m_s1;
			CGameSprite* pSpriteTarget = (bOverrideObject && pOverrideSprite) ? pOverrideSprite : &sprite;
					
			if (tCopy.m_i2 >= 0 && tCopy.m_i2 < BLOCK_VAR_ARRAY_SIZE) {
				if (tCopy.m_i == ARGTYPE_INT) {
					ParseStatement(tCopy.m_i2, tCopy.m_i, sStatement, *pSpriteTarget, pRuleEx->m_TriggerVars);
				} else if (tCopy.m_i == ARGTYPE_STR) {
					ParseStatement(tCopy.m_i2, tCopy.m_i, sStatement, *pSpriteTarget, pRuleEx->m_TriggerVars);
				}
			}

			//clean up
			bOverrideObject = FALSE;
			pOverrideSprite = NULL;
			break;
		} //TRIGGER_ASSIGN

		case TRIGGER_EVAL:
		{
			IECString sExpression = ParseBlockVariables(tCopy.m_s1, tCopy.m_i, pRuleEx->m_TriggerVars);
			int nLoc = (tCopy.m_i2 - 1) & 1;

			if (tCopy.m_i == ARGTYPE_INT) {
				int nValue = 0;
				MathPresso::Expression mpExp;
				MathPresso::mresult_t mpResult = mpExp.create(pRuleEx->m_mpContext, (LPCTSTR)sExpression);
				if (mpResult == MathPresso::MRESULT_OK) {
					nValue = mpExp.evaluate(NULL);
				} else {
					LPCTSTR lpsz = "Trigger Eval(): bad expression \"%s\" (error %d)\r\n";
					L.timestamp();
					L.appendf(lpsz, (LPCTSTR)sExpression, (int)mpResult);
					console.writef(lpsz, (LPCTSTR)sExpression, (int)mpResult);
				}

				bOverrideInt[nLoc] = TRUE;
				nOverride[nLoc] = nValue;
			} else if (tCopy.m_i == ARGTYPE_STR) {
				bOverrideStr[nLoc] = TRUE;
				sOverride[nLoc] = sExpression;
			}

			break;
		} //TRIGGER_EVAL

		default:
			//set OR value
			if (tCopy.m_wOpcode == TRIGGER_OR) {
				nOr = tCopy.m_i;
			} else nOr--;

			//substitute trigger parameters
			if (bOverrideInt[0]) {
				tCopy.m_i = nOverride[0];
				nOverride[0] = 0;
				bOverrideInt[0] = FALSE;
			}
			if (bOverrideInt[1]) {
				tCopy.m_i2 = nOverride[1];
				nOverride[1] = 0;
				bOverrideInt[1] = FALSE;
			}
			if (bOverrideStr[0]) {
				tCopy.m_s1 = sOverride[0];
				sOverride[0].Empty();
				bOverrideStr[0] = FALSE;
			}
			if (bOverrideStr[1]) {
				tCopy.m_s2 = sOverride[1];
				sOverride[1].Empty();
				bOverrideStr[1] = FALSE;
			}

			//evaluate trigger depending on override object
			if (bOverrideObject) {
				if (pOverrideSprite) {
					if ((tCopy.m_wOpcode & 0x4000) == 0) pt->DecodeIdentifiers(*pOverrideSprite); //workaround for 0x0XXX triggers that need the original trigger decoded to work properly
					bResult |= EvaluateTrigger(tCopy, triggers, *pOverrideSprite);
				} else bResult |= FALSE;
				bOverrideObject = FALSE;
				pOverrideSprite = NULL;
			} else {
				if ((tCopy.m_wOpcode & 0x4000) == 0) pt->DecodeIdentifiers(sprite); //workaround for 0x0XXX triggers that need the original trigger decoded to work properly
				bResult |= EvaluateTrigger(tCopy, triggers, sprite);
			}

			//terminate if not in OR
			if (bResult == FALSE &&	nOr <= 0) {
				//return FALSE;
				bResult = FALSE;
				bBreak = true;
			}

			break;
		} // switch(tCopy.opcode)
	} //while (pos != NULL)

	//clean up variables
	pRuleEx->m_TriggerVars.Empty();
	return bResult;
}