bool Command::Execute( void ) { switch( mCmdID ) { case kCmdAssign : return DoAssign(); case kCmdClose : return DoCloseCursor(); case kCmdExec : return DoExec(); case kCmdFetch : return DoFetch(); case kCmdGoIf : return DoGoIf(); case kCmdGoIfNot : return DoGoIfNot(); case kCmdOpen : return DoOpenCursor(); case kCmdParam : return DoReadParam(); case kCmdPrint : return DoPrint(); case kCmdReset : return mpVM->mVariables[ mObject ]->mIsNULL = true; case kCmdReturn : return DoReturn(); case kCmdSelect : return DoSelect(); case kCmdGo : mpVM->mPos = mParam.ToInt(); case kCmdNope : return true; default:; } return false; }
extern gui_ord GUIGetStringPos( gui_window *wnd, gui_ord indent, const char *string, int mouse_x ) { gui_coord diff; int guess; int length; int curr; int new_curr; bool got_new; if( indent > mouse_x ) { return( GUI_NO_COLUMN ); } got_new = GUIGetTheDC( wnd ); diff.x = mouse_x - indent; GUIScaleToScreenR( &diff ); length = strlen( string ); guess = length; curr = GUIGetTextExtentX( wnd, string, guess ); if( curr < diff.x ) { return( DoReturn( GUI_NO_COLUMN, wnd, got_new ) ); } if( curr == diff.x ) { return( DoReturn( (gui_ord)guess, wnd, got_new ) ); } guess = diff.x * (long)length / curr; curr = GUIGetTextExtentX( wnd, string, guess ); if( curr == diff.x ) { return( DoReturn( (gui_ord)guess, wnd, got_new ) ); } if( curr < diff.x ) { guess++; } else { guess--; } for( ; ; ) { new_curr = GUIGetTextExtentX( wnd, string, guess ); if( new_curr == diff.x ) { return( DoReturn( (gui_ord) guess, wnd, got_new ) ); } if( ( new_curr < diff.x ) && ( curr > diff.x ) ) { return( DoReturn( (gui_ord)guess, wnd, got_new ) ); } if( ( new_curr > diff.x ) && ( curr < diff.x ) ) { return( DoReturn( (gui_ord)guess - 1, wnd, got_new ) ); } if( new_curr < diff.x ) { guess++; } else { guess--; } curr = new_curr; } }
int singleStep (VM32Cpu * cpu) { unsigned char inst; unsigned char * ptr; /* Get an instruction */ ptr = (char *) cpu->pc; inst = *ptr; switch (inst) { /* Standard Op Codes */ case 0x00: DoBreak(cpu); break; case 0x01: DoNothing(cpu); break; case 0x02: DoCall(cpu); break; case 0x03: DoPushZero(cpu); break; case 0x04: DoPushImmediateNative(cpu); break; case 0x05: DoReturn(cpu); break; case 0x06: DoPop(cpu); break; case 0x07: DoSwap(cpu); break; case 0x08: DoSetupFrame(cpu); break; case 0x09: DoRestoreFrame(cpu); break; case 0x0a: CallNative(cpu); break; case 0x0b: DoPushSelf(cpu); break; case 0x0c: DoCheckArgCount(cpu); break; case 0x0d: DoBranch(cpu); break; case 0x0e: DoBranchIfTrue(cpu); break; case 0x0f: DoBranchIfFalse(cpu); break; default: DoInvalidInstruction(cpu); break; } return 0; }
void KAIBase::OnPursuit(void) { int nRetCode = false; BOOL bSkipKeepRange = false; KCharacter* pTarget = NULL; KNpc* pNpc = NULL; KNpcTemplate* pTemplate = NULL; int nSelectSkillIndex = 0; int nSkillExpectation = 0; DWORD dwSkillID = 0; DWORD dwSkillLevel = 0; DWORD dwSelectSkillID = 0; DWORD dwSelectSkillLevel = 0; KTarget Target; KGLOG_PROCESS_ERROR(m_pSelf); KGLOG_PROCESS_ERROR(IS_NPC(m_pSelf->m_dwID)); pNpc = (KNpc*)(m_pSelf); KGLOG_PROCESS_ERROR(pNpc); // 检查仇恨表是否为空 KThreatNode* pThreatNode = pNpc->m_ThreatList.GetFirstThreat(); if (!pThreatNode) { BOOL bReturn = true; // 组队情况下还要看队友的仇恨表 if (m_pNpcTeam) { pTarget = m_pNpcTeam->GetMemberTarget(); if (pTarget) { pNpc->m_ThreatList.ModifyThreat(pTarget, 0); bReturn = false; } } if (bReturn) { AI_TRACE("仇恨表空的,不打了回去!"); DoReturn(); goto Exit1; } pThreatNode = pThreatNode = pNpc->m_ThreatList.GetFirstThreat(); KGLOG_PROCESS_ERROR(pThreatNode); } //检测是否呼叫 CheckCallHeal(); // 检查技能状态 KG_PROCESS_SUCCESS(m_pSelf->m_OTActionParam.eActionType != otActionIdle); ASSERT(IS_NPC(m_pSelf->m_dwID)); pTemplate = ((KNpc*)m_pSelf)->m_pTemplate; KGLOG_PROCESS_ERROR(pTemplate); //没有普通攻击就表示怪物不能攻击,直接返回 KG_PROCESS_SUCCESS((pTemplate->dwSkillIDList[0] == 0) && (pTemplate->dwSkillLevelList[0] == 0)); // 选择技能和目标 if (g_pSO3World->m_nGameLoop >= pNpc->m_nSkillCommomCD) { for (int nSkillIndex = MAX_NPC_AI_SKILL - 1; nSkillIndex >= 0; nSkillIndex--) { dwSelectSkillID = pTemplate->dwSkillIDList[nSkillIndex]; dwSelectSkillLevel = pTemplate->dwSkillLevelList[nSkillIndex]; if (dwSelectSkillID == 0 || dwSelectSkillLevel == 0 || g_pSO3World->m_nGameLoop < pNpc->m_nSkillCastFrame[nSkillIndex]) { continue; } nSkillExpectation = GetSkillExpectation((AI_SKILL_TYPE)pTemplate->nAISkillType[nSkillIndex], (DWORD)nSkillIndex, &Target); if (nSkillExpectation == AI_IMMEDIATELY_CAST_EXP) { dwSkillID = dwSelectSkillID; dwSkillLevel = dwSelectSkillLevel; nSelectSkillIndex = nSkillIndex; break; } else { if (pTemplate->nSkillCastInterval[nSkillIndex] > g_pSO3World->m_Settings.m_ConstList.nNpcCommonShortCD) { //技能没有释放成功就进入公共短CD pNpc->m_nSkillCastFrame[nSkillIndex] = g_pSO3World->m_nGameLoop + g_pSO3World->m_Settings.m_ConstList.nNpcCommonShortCD; } else { pNpc->m_nSkillCastFrame[nSkillIndex] = g_pSO3World->m_nGameLoop + pTemplate->nSkillCastInterval[nSkillIndex]; } } } } //获取技能目标 if (Target.GetTargetType() == ttNpc || Target.GetTargetType() == ttPlayer) { nRetCode = Target.GetTarget(&pTarget); KGLOG_PROCESS_ERROR(nRetCode && pTarget); } // 朝向 if (pTarget && pTarget != m_pSelf && m_pSelf->m_eMoveState == cmsOnStand) { int nDirection = g_GetDirection(m_pSelf->m_nX, m_pSelf->m_nY, pTarget->m_nX, pTarget->m_nY); if (m_pSelf->m_nFaceDirection != nDirection) { m_pSelf->Turn(nDirection, true, true); } } // 释放技能 if (dwSkillID != 0 && dwSkillLevel != 0) { KSKILL_RECIPE_KEY RecipeKey; KSkill* pSkill = NULL; nRetCode = g_pSO3World->m_SkillManager.GetSkillRecipeKey(&RecipeKey, dwSkillID, dwSkillLevel, m_pSelf); if (!nRetCode) { KGLogPrintf( KGLOG_ERR, "Can't find npc skill, npc template id = %lu, skill id = %lu, skill level = %lu. Please check you config file. ", pNpc->m_dwTemplateID, dwSkillID, dwSkillLevel ); goto Exit0; } pSkill = g_pSO3World->m_SkillManager.GetSkill(RecipeKey); KGLOG_PROCESS_ERROR(pSkill); nRetCode = pSkill->CanCast(m_pSelf, Target); if (nRetCode == srcSuccess) { if (pSkill->m_nPrepareFrames > 0) { m_pSelf->Stop(); bSkipKeepRange = TRUE; } nRetCode = m_pSelf->CastSkill(dwSkillID, dwSkillLevel, Target); } if (nRetCode == srcTooFarTarget) { m_PursuitData.dwKeepDisDivisor++; if (m_PursuitData.dwKeepDisDivisor > 5) { m_PursuitData.dwKeepDisDivisor = 5; } } else { m_PursuitData.dwKeepDisDivisor = 1; } if (nRetCode == srcSuccess) { //技能释放成功进入正常CD,这块还没定,可能要等具体发出去了才进CD pNpc->m_nSkillCastFrame[nSelectSkillIndex] = g_pSO3World->m_nGameLoop + pTemplate->nSkillCastInterval[nSelectSkillIndex]; //设置公共CD pNpc->m_nSkillCommomCD = g_pSO3World->m_nGameLoop + g_pSO3World->m_Settings.m_ConstList.nNpcSkillCommonCD; // 判断目标的移动状态,更新仇恨范围 if (pTarget && pTarget->m_nVelocityXY == 0) { m_pSelf->m_ThreatList.UpdateKeepThreatField(); //更新仇恨区域 //m_pSelf->m_ThreatList.ModifyThreat(pTarget, 0); //更新仇恨 bSkipKeepRange = true; } } else { //技能没有释放成功就进入公共短CD if (pTemplate->nSkillCastInterval[nSelectSkillIndex] > g_pSO3World->m_Settings.m_ConstList.nNpcCommonShortCD) { pNpc->m_nSkillCastFrame[nSelectSkillIndex] = g_pSO3World->m_nGameLoop + g_pSO3World->m_Settings.m_ConstList.nNpcCommonShortCD; } else { pNpc->m_nSkillCastFrame[nSelectSkillIndex] = g_pSO3World->m_nGameLoop + pTemplate->nSkillCastInterval[nSelectSkillIndex]; } } } //获取第一仇恨的目标 pTarget = pThreatNode->pCharacter; KGLOG_PROCESS_ERROR(pTarget); // 维持距离 if (!bSkipKeepRange) { KSkill* pSkill = NULL; KSKILL_RECIPE_KEY RecipeKey; nRetCode = g_pSO3World->m_SkillManager.GetSkillRecipeKey(&RecipeKey, pTemplate->dwSkillIDList[0], pTemplate->dwSkillLevelList[0], m_pSelf); KGLOG_PROCESS_ERROR(nRetCode); pSkill = g_pSO3World->m_SkillManager.GetSkill(RecipeKey); KGLOG_PROCESS_ERROR(pSkill); if (pNpc->m_nPathFindAstar) { KeepAttackRangeAStar(pTarget, pSkill); } else { KeepAttackRange(pTarget, pSkill); } } Exit1: Exit0: return; }