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; }
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; }