/** ** Missile flies from x,y to x1,y1 than bounces NumBounces times */ void MissilePointToPointBounce::Action() { this->Wait = this->Type->Sleep; if (PointToPointMissile(this)) { if (this->State < 2 * this->Type->NumBounces - 1 && this->TotalStep) { int xstep; int ystep; xstep = (this->DX - this->SourceX) * 1024 / this->TotalStep; ystep = (this->DY - this->SourceY) * 1024 / this->TotalStep; this->DX += xstep * (TileSizeX + TileSizeY) * 3 / 4 / 1024; this->DY += ystep * (TileSizeX + TileSizeY) * 3 / 4 / 1024; this->State++; // !(State & 1) to initialise this->SourceX = this->X; this->SourceY = this->Y; PointToPointMissile(this); //this->State++; MissileHit(this); // FIXME: hits to left and right // FIXME: reduce damage effects on later impacts } else { MissileHit(this); this->TTL = 0; } } else { NextMissileFrame(this, 1, 0); } }
/** ** Missile don't move, than disappears */ void MissileStay::Action() { this->Wait = this->Type->Sleep; if (NextMissileFrame(this, 1, 0)) { MissileHit(this); this->TTL = 0; } }
/** ** Missile flies from x,y to x1,y1 using a parabolic path */ void MissileParabolic::Action() { this->Wait = this->Type->Sleep; if (ParabolicMissile(this)) { MissileHit(this); this->TTL = 0; } else { NextMissileFrameCycle(this); } }
/** ** Missile flies from x,y to x1,y1 and stays there for a moment */ void MissilePointToPointCycleOnce::Action() { this->Wait = this->Type->Sleep; if (PointToPointMissile(this)) { MissileHit(this); this->TTL = 0; } else { NextMissileFrameCycle(this); } }
/** ** Missile flies from x,y to x1,y1 showing the first frame ** and then shows a hit animation. */ void MissilePointToPointWithHit::Action() { this->Wait = this->Type->Sleep; if (PointToPointMissile(this)) { if (NextMissileFrame(this, 1, 0)) { MissileHit(this); this->TTL = 0; } } }
/** ** Missile doesn't move, it will just cycle once and vanish. ** Used for ui missiles (cross shown when you give and order) */ void MissileCycleOnce::Action() { this->Wait = this->Type->Sleep; switch (this->State) { case 0: case 2: ++this->State; break; case 1: if (NextMissileFrame(this, 1, 0)) { ++this->State; } break; case 3: if (NextMissileFrame(this, -1, 0)) { MissileHit(this); this->TTL = 0; } break; } }
//FIXME: (Fabrice) I don't know if my update for missile visibility is fully //correct. global void MissileActions(void) { int missile; for( missile=0; missile<NumMissiles; ++missile ) { if( Missiles[missile].Type==MissileFree ) { continue; } if( Missiles[missile].Wait-- ) { continue; } if (MissileVisible(missile)) { // check before movement MustRedraw|=RedrawMap; } switch( Missiles[missile].Type->Class ) { case MissileClassPointToPoint: Missiles[missile].Wait=1; if( PointToPointMissile(missile) ) { MissileHit(missile); Missiles[missile].Type=MissileFree; } else { // // Animate missile, cycle through frames // Missiles[missile].Frame+=5; if( (Missiles[missile].Frame&127) >=Missiles[missile].Type->RleSprite->NumFrames ) { Missiles[missile].Frame= // (Missiles[missile].Frame&128)| (Missiles[missile].Frame -Missiles[missile].Type->RleSprite ->NumFrames); } DebugLevel3("Frame %d of %d\n" ,Missiles[missile].Frame ,Missiles[missile].Type->RleSprite->NumFrames); } break; case MissileClassPointToPointWithDelay: Missiles[missile].Wait=1; if( PointToPointMissile(missile) ) { switch( Missiles[missile].State++ ) { case 1: // FIXME: bounces up. PlayMissileSound(Missiles+missile, Missiles[missile].Type->ImpactSound.Sound); // FIXME: make this configurable!! switch( Missiles[missile].Type->Type ) { case MissileSmallCannon: MakeMissile(MissileCannonExplosion ,Missiles[missile].X ,Missiles[missile].Y ,0,0); break; case MissileBigCannon: MakeMissile(MissileCannonTowerExplosion ,Missiles[missile].X ,Missiles[missile].Y ,0,0); break; case MissileCatapultRock: case MissileBallistaBolt: MakeMissile(MissileImpact ,Missiles[missile].X ,Missiles[missile].Y ,0,0); break; } break; default: MissileHit(missile); Missiles[missile].Type=MissileFree; break; } } else { // // Animate missile, depends on the way. // // FIXME: how? } break; case MissileClassPointToPoint3Bounces: Missiles[missile].Wait=1; if( PointToPointMissile(missile) ) { // // 3 Bounces. // switch( Missiles[missile].State ) { case 1: case 3: case 5: Missiles[missile].State+=2; Missiles[missile].DX+= Missiles[missile].Xstep*TileSizeX*2; Missiles[missile].DY+= Missiles[missile].Ystep*TileSizeY*2; PlayMissileSound(Missiles+missile, Missiles[missile].Type->ImpactSound.Sound); MakeMissile(MissileExplosion ,Missiles[missile].X ,Missiles[missile].Y ,0,0); MissileHit(missile); // FIXME: hits to left and right // FIXME: reduce damage break; default: Missiles[missile].Type=MissileFree; break; } } else { // // Animate missile, cycle through frames // Missiles[missile].Frame+=5; if( (Missiles[missile].Frame&127) >=Missiles[missile].Type->RleSprite->NumFrames ) { Missiles[missile].Frame= // (Missiles[missile].Frame&128)| (Missiles[missile].Frame -Missiles[missile].Type->RleSprite ->NumFrames); } DebugLevel3("Frame %d of %d\n" ,Missiles[missile].Frame ,Missiles[missile].Type->RleSprite->NumFrames); } break; case MissileClassPointToPointWithHit: Missiles[missile].Wait=1; if( PointToPointMissile(missile) ) { // // Animate hit // Missiles[missile].Frame+=5; if( (Missiles[missile].Frame&127) >=Missiles[missile].Type->RleSprite->NumFrames ) { MissileHit(missile); Missiles[missile].Type=MissileFree; } } break; case MissileClassStayWithDelay: Missiles[missile].Wait=1; if( ++Missiles[missile].Frame ==Missiles[missile].Type->RleSprite ->NumFrames ) { MissileHit(missile); Missiles[missile].Type=MissileFree; } break; case MissileClassCycleOnce: Missiles[missile].Wait=Missiles[missile].Type->Speed; switch( Missiles[missile].State ) { case 0: case 2: ++Missiles[missile].State; break; case 1: if( ++Missiles[missile].Frame ==Missiles[missile].Type->RleSprite ->NumFrames ) { --Missiles[missile].Frame; ++Missiles[missile].State; } break; case 3: if( !Missiles[missile].Frame-- ) { MissileHit(missile); Missiles[missile].Type=MissileFree; } break; } break; } if (Missiles[missile].Type!=MissileFree && MissileVisible(missile)) { // check after movement MustRedraw|=RedrawMap; } } }