Exemplo n.º 1
0
void BAttackAnimEvent::run()
{
	Sint32 xtiles, ytiles;
	Uint16 atkpos, mwid;
	float alpha;
	Uint8 facing;
	mwid = p::ccmap->getWidth();

	if ( !strct->isAlive() || done)
	{
		delete this;
		return;
	}

	if (!target->isAlive() || done)
	{
		if (strct->getType()->Charges())
		{
			if (strct->getNumbImages(0) > frame)
			{
				strct->setImageNum(frame, 0);
			}
			else
			{
				logger->error("%s line %i: Failed to set frame %i\n",__FILE__ , __LINE__, frame);
			}
		}
		delete this;
		return;
	}
	atkpos = target->getPos();

	xtiles = strct->getPos() % mwid - atkpos % mwid;
	ytiles = strct->getPos() / mwid - atkpos / mwid;

	// @todo modify calculs
	//distance = abs()>abs(ytiles)?abs(xtiles):abs(ytiles);



	double distance = sqrt(((double)xtiles*xtiles + ytiles*ytiles));
	if (distance > strct->getType()->getWeapon()->getRange())
	{
		// Since buildings can not move, give up for now.
		// Alternatively, we could just wait to see if the target ever
		// enters range (highly unlikely when the target is a structure)
		if (strct->getType()->Charges())
		{
			if (strct->getNumbImages (0)> frame)
			{
				strct->setImageNum(frame,0);
			}
			else
			{
				logger->error ("%s line %i: Failed to set frame %i\n", __FILE__, __LINE__, frame);
			}
		}
		delete this;
		return;
	}
	//Make sure we're facing the right way
	if( xtiles == 0 )
	{
		if( ytiles < 0 )
		{
			alpha = (float)-M_PI_2;
		}
		else
		{
			alpha = (float)M_PI_2;
		}
	}
	else
	{
		alpha = atan((float)ytiles/(float)xtiles);
		if( xtiles < 0 )
		{
			alpha = (float)M_PI+alpha;
		}
	}
	facing = (40-(Sint8)(alpha*16/M_PI))&0x1f;

	//
	// turn to face target first if this building have turret
	//
	if ((strct->getType()->hasTurret()) && ((strct->getImageNums()[0]&0x1f)!=facing) )
	{
		setDelay(0);
		strct->buildAnim = new BTurnAnimEvent(strct->type->getTurnspeed(), strct, facing);
		strct->buildAnim->setSchedule(this, true);
		p::aequeue->scheduleEvent(strct->buildAnim);
		return;
	}

	//
	// This is the charging animation I only know of the tesla coil that uses it.
	//
	if (strct->getType()->Charges())
	{
		if (frame < StartFrame+8)
		{
			if (NeedToCharge)
			{
				frame = (Uint8) StartFrame;				//desired conversion?
				char* Snd = 0;
				Snd = strct->getType()->getWeapon()->getChargingSound();
				if (Snd != 0){
					pc::sfxeng->PlaySound(Snd);
					delete Snd;
				}
				Snd = 0;
				NeedToCharge = false;
			}
			if (strct->getNumbImages (0)> frame)
			{
				strct->setImageNum(frame,0);
			}
			else
			{
				logger->error ("%s line %i: Failed to set frame %i\n", __FILE__, __LINE__, frame);
			}
			frame++;
			// Reschedule this..
			setDelay(3);
			p::aequeue->scheduleEvent(this);
			return;
		}
		frame = (Uint8) StartFrame;						//desired conversion?
		if (strct->getNumbImages (0)> frame)
		{
			strct->setImageNum(frame,0);
		}
		else
		{
			logger->error ("%s line %i: Failed to set frame %i\n", __FILE__, __LINE__, frame);
		}
		NeedToCharge = true;
	}

	// Throw an event
	HandleTriggers(target, TRIGGER_EVENT_ATTACKED,
		    		p::ppool->getHouseNumByPlayerNum(strct->getOwner()));

	// We can shoot
	strct->getType()->getWeapon()->fire(strct, target->getBPos(strct->getPos()), target->getSubpos());
	setDelay(strct->getType()->getWeapon()->getReloadTime());
	p::aequeue->scheduleEvent(this);
}
void UInfiltrateAnimEvent::run()
{
    //Uint32 distance;
    Sint32 xtiles, ytiles;
    Uint16 atkpos;
    //float alpha;
    //Uint8 facing = 0;
#ifdef LOOPEND_TURN
    //Uint8 loopend2=((UnitType*)un->getType())->getAnimInfo().loopend2;
#endif

    MACRO_LOG_DEBUG("Infiltrate run t%p u%p\n")//,this,un);
    
    waiting = 0;
    if( !un->isAlive() || stopping ) {
        delete this;
        return;
    }

    if( !target->isAlive() || stopping) {
        if ( !target->isAlive() ) {
            un->doRandTalk(TB_postkill);
        }
        delete this;
        return;
    }
	
    atkpos = un->getTargetCell();

    xtiles = un->getPos() % p::ccmap->getWidth() - atkpos % p::ccmap->getWidth();
    ytiles = un->getPos() / p::ccmap->getWidth() - atkpos / p::ccmap->getWidth();
    
    // @todo modify calculs
    //distance = abs()>abs(ytiles)?abs(xtiles):abs(ytiles);
    //distance = sqrt(xtiles*xtiles + ytiles*ytiles);
    
    //if( distance > un->type->getWeapon(UsePrimaryWeapon)->getRange() /* weapons range */ ) {
    if (xtiles<=1 && ytiles<=1)
    {
        MACRO_LOG_DEBUG("Infiltrate MOVE !!")


        setDelay(0);
        waiting = 3;
        un->move(atkpos, false);
        un->moveanim->setRange(1);//un->type->getWeapon(UsePrimaryWeapon)->getRange());
        un->moveanim->setSchedule(this);
        return;
    }
/*    
    //Make sure we're facing the right way
    if( xtiles == 0 ) {
        if( ytiles < 0 ) {
            alpha = -1.57079632679489661923;
        } else {
            alpha = 1.57079632679489661923;
        }
    } else {
        alpha = atan((float)ytiles/(float)xtiles);
        if( xtiles < 0 ) {
            alpha = 3.14159265358979323846+alpha;
        }
    }
    
#ifdef LOOPEND_TURN
    facing = ((Sint8)((loopend2+1)*(1-alpha/2/3.14159265358979323846)+8))&loopend2;
    if (un->type->isInfantry()) {
        if (facing != (un->getImageNum(0)&loopend2)) {
            un->setImageNum((Sint8)((loopend2+1)*facing/8),0);
        }
    } else if (un->type->getNumLayers() > 1 ) {
        if (abs((int)(facing - (un->getImageNum(1)&loopend2))) > un->type->getROT()) {
#else
    facing = (40-(Sint8)(alpha*16/M_PI))&0x1f;
    if (un->type->isInfantry()) {
        if (facing != (un->getImageNum(0)&0x1f)) {
			un->setImageNum(facing>>2,0);
        }
    } else if (un->type->getNumLayers() > 1 ) {
        if (abs((int)(facing - (un->getImageNum(1)&0x1f))) > un->type->getROT()) {
#endif
            setDelay(0);
            waiting = 2;
            un->turn(facing,1);
            un->turnanim2->setSchedule(this);
            return;
        }
    } else {
#ifdef LOOPEND_TURN
        if (abs((int)(facing - un->getImageNum(0)&loopend2)) > un->type->getROT()) {
#else
        if (abs((int)(facing - un->getImageNum(0)&0x1f)) > un->type->getROT()) {
#endif
            setDelay(0);
            waiting = 1;
            un->turn(facing,0);
            un->turnanim1->setSchedule(this);
            return;
        }
    }
*/
	// If we have a healing weapon we don't want to heal a enemy
	/*if (un->getType()->getWeapon(UsePrimaryWeapon)->getDamage() < 0){
		if (un->getOwner() != target->getOwner()){
			delete this;
			return;
		}
	}*/

	// Throw an event
    // @todo FINISH THIS
	HandleTriggers(target, TRIGGER_EVENT_ENTERED_BY,
	    		p::ccmap->getPlayerPool()->getHouseNumByPlayerNum(un->getOwner()));

	if (target->getType()->isStructure()){
		((Structure*)target)->bomb();
	}
	
	// @todo CREATE THE BOMB ANIM
    // We can shoot
    //un->type->getWeapon(UsePrimaryWeapon)->fire(un, target->getBPos(un->getPos()), target->getSubpos());
    // set delay to reloadtime
    //setDelay(3);//un->type->getWeapon(UsePrimaryWeapon)->getReloadTime());
    //waiting = 4;
    //p::aequeue->scheduleEvent(this);
	//done = 1;
	
	MACRO_LOG_DEBUG("END INFILTRATE !!!")

    delete this;
    return;
}