void EntMobile::UpdateMovement(float dt)
{
	if (movement)
	{
		if (!target_reached)
		{
			UpdateVelocity(dt);
			Move(dt);
			if (IsTargetReached())
				target_reached = true;
		}
		else
		{
			GetNewTarget();
		}
	}
}
void AIRayPathFinderStrategy::Step(unsigned timeMs)
{
	//if (!Inited)
	//	Init();	
	//Ogre::SceneNode *Node = Parent->GetNode();
	// определить вектор на цель и двигаться по нему с

	ClosestObj = NULL;
	
    // заданной скоростью.

    IPhysical *phys = Parent->GetPhysical();
    assert(phys);

	//if (phys->IsCollided())
	//{		
 //       //int diff=timeMs-StartFreeFlyingTime;
 //       StartFreeFlyingTime+=timeMs;
 //       if (StartFreeFlyingTime>FREE_FLY_TOUT || phys->GetRotVelocity().isZeroLength()) 
 //       {
 //           StartFreeFlyingTime=0;
 //           phys->SetCollided(false);                
 //       }
	//}

	/* 
	если преграда - статический объект, то облетаем и движемся по ВП
	если преграда - целевой объект, то его не облетаем
	если преграда - динамический объект, то облетаем, но не дожидаемся достижения ВП
	*/
	Vector3 point;
	static Vector3 prev_forward_direction(0,0,0);

    AIPathFinderStrategy::Step(timeMs);

	if (TargetType != TT_NONE) 
	{	
		if (HaveCashedTarget)
		{
			point = CashedTargetPoint;
			Vector3 dist = point-Parent->GetScenable()->GetPosition();
			//if (dist.squaredLength()>100.f*100.f)
            if (!IsTargetReached(CashedTargetPoint))
			{                
                LastChangingDirectionTime+=timeMs;
				if (ClosestObj && ClosestObj->GetScenable()->GetType()==PT_DYNAMIC && LastChangingDirectionTime>CHANGE_DIRECTION_TOUT) 
				{   
                    LastChangingDirectionTime = 0;
					HaveCashedTarget = false;
					point = RouteToTarget();					
				} else
					Route(point);
			}
			else
			{
				HaveCashedTarget = false;
				point = RouteToTarget();
			}
		} else
		{
			point = RouteToTarget();
		}
		if (LastTargetPoint!=point)
		{
			LastChangingDirectionTime = 0;
			LastTargetPoint = point;
		}
	}	
}
Exemple #3
0
void CCharacter::DoAttack( )
{
    //if(Status->Sleep <= 0xff)
    //{
    //    ClearBattle( Battle );
    //    return; // can't take any action while we are asleep can we?
    //}
    //Log(MSG_INFO,"skill type %i selected. Chartype = %i",Battle->atktype, CharType);
    if(Battle->iscasting == 1) 
    {
        CCharacter* Enemy = GetCharTarget( );
        if(Enemy == NULL)
        {
            ClearBattle( Battle );
            return;
        }
        //Log(MSG_DEBUG,"Iscasting detected as true. Reset to false.");
        if(CanAttack())
        {
            //if(IsPlayer())
            //{
            //    Log(MSG_DEBUG,"Should reach here once on normal attack. iscasting state = %i",Battle->iscasting);
            //}
            ClearBattle( Battle );
            StartAction(Enemy, NORMAL_ATTACK, 0);
        }
        else
        {
            return;
        }
        return;
    }
    if(!CanAttack())
    {
        return;
    }
    if(IsSummon())
    {
        CCharacter* Enemy = GetCharTarget( );
        if(Enemy == NULL || (Battle->atktype != SKILL_AOE && Battle->atktype != BUFF_AOE))
        {
            //Log(MSG_DEBUG,"No Enemy found");
            ClearBattle( Battle );
            return;
        }
        if(this == Enemy) //summoned monster is attacking itself. It has been observed to happen
        {
            //Log(MSG_INFO,"Clearing Battle for this summon");
            ClearBattle( Battle );
            return;
        }
        if(Enemy->IsSummon())
        {
            CMonster* thisMonster = reinterpret_cast<CMonster*>(this);
            if(thisMonster == NULL)
            {
                ClearBattle( Battle );
                return;           
            }
            CMonster* otherMonster = reinterpret_cast<CMonster*>(Enemy);
            if(otherMonster == NULL)
            {
                ClearBattle( Battle );
                return;           
            }
            if(thisMonster->owner == otherMonster->owner)
            {
                //Log(MSG_INFO,"Clearing Battle for this summon");
                ClearBattle( Battle );
                return;                    
            }                
        }
    }
    CMap* map = GServer->MapList.Index[Position->Map];
    //Log(MSG_INFO,"DoAttack Battle Attack type = %i",Battle->atktype);
    switch(Battle->atktype)
    {
        case NORMAL_ATTACK://normal attack
        {
            //if(!Status->CanAttack)
            //    return; //can't attack right now.
            CCharacter* Enemy = GetCharTarget( );
            if(Enemy == NULL)
            {
                ClearBattle( Battle );
                return;
            }
            if(Enemy == this)
            {
                //Log(MSG_INFO,"WTF?? I AM trying to attack myself");
                ClearBattle( Battle );
            }
            if(IsTargetReached( Enemy ))
            {
                //if(IsMonster())
                //    Log(MSG_INFO,"Monster is trying to hit the player");
                NormalAttack( Enemy );
                if (Enemy->IsMonster()) // do monster AI script when monster is attacked.
                {
                    CMonster* monster = GServer->GetMonsterByID(Enemy->clientid, Enemy->Position->Map);
                    if(monster == NULL)return;
                    //monster->DoAi(monster->thisnpc->AI, 3);
                    monster->DoAi(monster->monAI, 3);
                }
            }
        }
        break;
        case SKILL_ATTACK://skill attack
        {
            CCharacter* Enemy = GetCharTarget( );
            if(Enemy == NULL)
            {
                ClearBattle( Battle );
                return;
            }
            CSkills* skill = GServer->GetSkillByID( Battle->skillid );
            if(skill == NULL)
            {
                //ClearBattle( Battle );
                return;
            }
            if(IsTargetReached( Enemy, skill )) 
            {
                SkillAttack( Enemy, skill );
                if (Enemy->IsMonster())
                {
                    CMonster* monster = GServer->GetMonsterByID(Enemy->clientid, Enemy->Position->Map);
                    if(monster == NULL)return;
                    monster->DoAi(monster->monAI, 3);
                }
            }
        }
        break;
        case SKILL_BUFF://buffs
        {


            CCharacter* Enemy = GetCharTarget( );
            if(Enemy == NULL)
            {
                //Log(MSG_DEBUG,"this target is NULL");
                ClearBattle( Battle );
                return;
            }
            CSkills* skill = GServer->GetSkillByID( Battle->skillid );
            if(skill == NULL)
            {
                //Log(MSG_DEBUG,"this skill is NULL");
                return;
            }

            if(IsTargetReached( Enemy, skill ))
            {
                //Log(MSG_DEBUG,"Skill successfully cast");
                BuffSkill( Enemy, skill );
            }
        }
        break;
        case SKILL_AOE:
        //case SKILL_SELF: //this is impossible. it can never be set
        case AOE_TARGET:
        {


            //Log(MSG_DEBUG,"Called skill type %i",Battle->atktype);
            CCharacter* Enemy = NULL;
            CSkills* skill = GServer->GetSkillByID( Battle->skillid );
            if(skill == NULL)
            {
                ClearBattle( Battle );
                return;
            }
            if(Battle->atktype == AOE_TARGET)
            {
                float distance = GServer->distance( Position->current, Position->destiny );
                if(distance <= skill->range)
                {
                    Position->destiny = Position->current;
                    AoeSkill( skill, Enemy );
                }
            }
            else
            {
                Position->skilltargetpos = Position->current;
                AoeSkill( skill, NULL );
            }
        }
        break;
        case BUFF_SELF:
        {

            //    return; // can't cast skills right now
            CSkills* skill = GServer->GetSkillByID( Battle->skillid );
            if(skill == NULL)
            {
                //ClearBattle( Battle );
                return;
            }
            BuffSkill( this, skill );
        }
        break;
        case BUFF_AOE:
        {
            //Log(MSG_INFO,"BUFF AOE selected");
            CSkills* skill = GServer->GetSkillByID( Battle->skillid );
            if(skill == NULL)
            {
                //ClearBattle( Battle );

                return;
            }
            AoeBuff( skill );
        }
        break;
        default:
            return;
        break;
    }
}