Exemplo n.º 1
0
	bool FightStateNormal::SearchSkill(CMonster *monster, long dis)
	{
		if (monster == NULL)
		{
			LogError(AI_MODULE, "monster object is null.");
			return false;
		}
        // 选择周期技能
        if(SearchSkill(SKILLTYPE_CYCLE, monster, dis))
        {
            return true;
        }
        unsigned long thisTime = timeGetTime();
        if(thisTime > m_NormalSkillTimeStamp)
        {
            m_NormalSkillTimeStamp = thisTime + monster->GetSkillSpace();
            int proportion = monster->GetSkillProportion();
            if(random(100) < proportion)
            {
                // 选择普通技能
                if(SearchSkill(SKILLTYPE_NORMAL, monster, dis))
                {
                    return true;
                }
            }
        }
        // 选择基本技能
		return SearchSkill(SKILLTYPE_BASE, monster, dis);
	}
INT	CFixedPositionArcher::Tracing(CMoveShape*pTarget)
{
	SearchSkill(pTarget);

	CBaseModule* basemodule=0;
	stStaticModuParam* moduparam=0;
	BOOL  HasSkill=TRUE;
	INT MinAtkDistance=0;
	INT MaxAtkDistance=0;

	if (HasChoiceSkill())
	{
		basemodule=dynamic_cast<CMonster*>(m_pOwner)->GetActiveSkill(0);//GetSearchedSkillKey()
	}
	else
	{
		Stand(dynamic_cast<CMonster*>(m_pOwner)->GetStopFrame());
		WhenLoseTarget();
		return TRACE_RESULT_TRACE;
	}




	if (basemodule!=NULL)
	{
		moduparam=basemodule->GetStaticParam();
		MinAtkDistance=moduparam->lMinAtkDistance;
		MaxAtkDistance=moduparam->lMaxAtkDistance;
	}
	else
	{
		Stand(dynamic_cast<CMonster*>(m_pOwner)->GetStopFrame());
		WhenLoseTarget();
		return TRACE_RESULT_TRACE;
	}

	//##合乎距离要求。
	LONG lDistance = m_pOwner -> RealDistance( pTarget );

	//如果在技能的距离内, 则使用技能
	if(lDistance >= MinAtkDistance && lDistance <= MaxAtkDistance )
	{
		if (HasSkill)
		{
			return TRACE_RESULT_SUCCESS;
		}
		else
		{
			Stand(dynamic_cast<CMonster*>(m_pOwner)->GetStopFrame());
			WhenLoseTarget();
			return TRACE_RESULT_TRACE;
		}

	}
	//##如果依然在追击范围内,就开始跟随玩家。
	else
	{
		Stand(dynamic_cast<CMonster*>(m_pOwner)->GetStopFrame());
		return TRACE_RESULT_TRACE;

	}
}
Exemplo n.º 3
0
	void FightStateNormal::Attack(BaseType::EntityType *entity, CMoveShape *target)
	{
		if (entity == NULL)
		{
			LogError(AI_MODULE, "Attack entity object is null.");
			return;
		}
		if (target == NULL)
		{
			LogError(AI_MODULE, "Target to be attacked is null.");
			return;
		}
		CMonster *monster= static_cast<CMonster*>(entity->GetOwner());
        long targetDis = monster->RealDistance(target);
		if(m_SelSkill.id == 0)
		{
			// search one skill to attack
			if(!SearchSkill(monster, targetDis))
			{
				entity->Resume(OPER_FAILED_TIME);
				return ;
			}
		}

		// we assume we have one skill to attack the target
		if(!GetInst(SkillAttribute).IsExist(m_SelSkill.id , m_SelSkill.level))
		{
			// error
			entity->Resume(OPER_FAILED_TIME);
			ClearSelSkill();
			return ;
		}

		float minAtkDis = (float)monster->GetSkillValue(m_SelSkill.id , m_SelSkill.level , "MinAtkDistance");
		float maxAtkDis = (float)monster->GetSkillValue(m_SelSkill.id , m_SelSkill.level , "MaxAtkDistance");

        bool used = false;

		// we assume the target is still in the track range.
		if(targetDis > maxAtkDis)
		{
			entity->Move(target->GetTileX(), target->GetTileY());
		}
		else if(targetDis < minAtkDis)
		{
			long dir = GetLineDir(target->GetTileX(), target->GetTileY(),
				monster->GetTileX(), monster->GetTileY());
			entity->Move(dir);
		}
		else
		{
			// in the attack range
			if(static_cast<MonsterAI*>(entity)->BeginSkill(m_SelSkill.id, m_SelSkill.level,
				target->GetTileX(), target->GetTileY(), target))
			{
				// use this skill ok, clear the selection.
				OnSkillUsed(monster);
                used = true;
			}
		}
        // clear the selected skill if it's not a cycle skill
        if(!used && m_SelSkill.type != SKILLTYPE_CYCLE)
        {
            ClearSelSkill();
        }
	}