diff --git a/src/action/action_stand.cpp b/src/action/action_stand.cpp
index f2fc4d023..e8acd4164 100644
--- a/src/action/action_stand.cpp
+++ b/src/action/action_stand.cpp
@@ -85,6 +85,7 @@ global void HandleActionStandGround(Unit* unit)
 	return;
     }
 
+#if 0
     //
     //	Building:	burning FIXME: must moved to general point
     //
@@ -114,6 +115,7 @@ global void HandleActionStandGround(Unit* unit)
 	    }
 	}
     }
+#endif
 
 #if 0
     // JOHNS: critters removed here
diff --git a/src/action/action_still.cpp b/src/action/action_still.cpp
index ef8da7082..f8e5b641b 100644
--- a/src/action/action_still.cpp
+++ b/src/action/action_still.cpp
@@ -82,6 +82,7 @@ global void HandleActionStill(Unit* unit)
 	return;
     }
 
+#if 0
     //
     //	Building:	burning FIXME: must moved to general point
     //
@@ -111,6 +112,7 @@ global void HandleActionStill(Unit* unit)
 	    }
 	}
     }
+#endif
 
 #if 1  // a unit with type->Vanishes is _dying_.
     //
diff --git a/src/include/unit.h b/src/include/unit.h
index f7cb7357e..e863f7656 100644
--- a/src/include/unit.h
+++ b/src/include/unit.h
@@ -232,6 +232,7 @@ struct _unit_ {
     unsigned	Heading : 8;		/// direction of unit looking
 #endif
 
+    unsigned	Burning : 1;		/// unit is burning
     unsigned	Attacked : 1;		/// unit is attacked
     // FIXME: next not used!
     //unsigned	Visible : 1;		/// unit is visible (submarine)
diff --git a/src/stratagus/oldmissile.cpp b/src/stratagus/oldmissile.cpp
index be9c429b2..9db649ba4 100644
--- a/src/stratagus/oldmissile.cpp
+++ b/src/stratagus/oldmissile.cpp
@@ -92,6 +92,10 @@
 **	Missile flies from x,y to x1,y1 than shows hit animation.
 */
 #define MissileClassPointToPointWithHit		11
+/**
+**	Missile don't move, than checks the source unit for HP.
+*/
+#define MissileClassFire			12
 
 /*----------------------------------------------------------------------------
 --	Variables
@@ -308,16 +312,16 @@ global MissileType MissileTypes[MissileTypeMax] = {
     "small fire.png",
     32,48,
     { NULL },
-    MissileClassStayWithDelay,	
-    1,
+    MissileClassFire,	
+    8,
     },
 { MissileTypeType,
     "missile-big-fire",
     "big fire.png",
     48,48,
     { NULL },
-    MissileClassStayWithDelay,	
-    1,
+    MissileClassFire,	
+    8,
     },
 { MissileTypeType,
     "missile-impact",
@@ -394,6 +398,12 @@ global MissileType MissileTypes[MissileTypeMax] = {
     },
 };
 
+/*
+**	Next missile types are used hardcoded in the source.
+*/
+global MissileType* MissileTypeSmallFire;	/// Small fire missile type
+global MissileType* MissileTypeBigFire;		/// Big fire missile type
+
 #define MAX_MISSILES	1800		/// maximum number of missiles
 
 local int NumMissiles;			/// currently used missiles
@@ -443,6 +453,11 @@ global void LoadMissileSprites(void)
 		    =MissileTypeByIdent(MissileTypes[i].ImpactName);
 	}
     }
+
+    MissileTypeSmallFire=MissileTypeByIdent("missile-small-fire");
+    // FIXME: FIXME: FIXME: very diry hack
+    MissileTypeSmallFire->RleSprite->NumFrames=6;
+    MissileTypeBigFire=MissileTypeByIdent("missile-big-fire");
 }
 
 /**
@@ -503,10 +518,10 @@ global Missile* MakeMissile(MissileType* type,int sx,int sy,int dx,int dy)
     missile=Missiles+NumMissiles++;
 
 found:
-    missile->X=sx;
-    missile->Y=sy;
-    missile->DX=dx;
-    missile->DY=dy;
+    missile->X=sx-type->Width/2;
+    missile->Y=sy-type->Height/2;
+    missile->DX=dx-type->Width/2;
+    missile->DY=dy-type->Height/2;
     missile->Type=type;
     missile->Frame=0;
     missile->State=0;
@@ -643,7 +658,7 @@ global void FireMissile(Unit* unit)
 
     // FIXME: goal is already dead, but missile could hit others?
 
-    x=unit->X*TileSizeX+TileSizeX/2;
+    x=unit->X*TileSizeX+TileSizeX/2;	// missile starts in tile middle
     y=unit->Y*TileSizeY+TileSizeY/2;
     if( (goal=unit->Command.Data.Move.Goal) ) {
 #ifdef NEW_UNIT
@@ -696,10 +711,10 @@ local int MissileVisible(const Missile* missile)
     int tileMinY;
     int tileMaxY;
 
-    tileMinX=(missile->X-missile->Type->Width/2)/TileSizeX;
-    tileMinY=(missile->Y-missile->Type->Height/2)/TileSizeY;
-    tileMaxX=(missile->X+missile->Type->Width/2)/TileSizeX;
-    tileMaxY=(missile->Y+missile->Type->Height/2)/TileSizeY;
+    tileMinX=missile->X/TileSizeX;
+    tileMinY=missile->Y/TileSizeY;
+    tileMaxX=(missile->X+missile->Type->Width)/TileSizeX;
+    tileMaxY=(missile->Y+missile->Type->Height)/TileSizeY;
     if ( (tileMinX>(MapX+MapWidth)) || (tileMaxX<MapX)
 	    || (tileMinY>MapY+MapHeight) || (tileMaxY<MapY)) {
 	return 0;
@@ -715,10 +730,6 @@ local int MissileVisible(const Missile* missile)
 */
 global void DrawMissile(const MissileType* type,int frame,int x,int y)
 {
-    // FIXME: remove this here, move to higher functions
-    x-=type->Width/2;
-    y-=type->Height/2;
-
     // FIXME: This is a hack for mirrored sprites
     if( frame&128 ) {
 	DrawRleSpriteClippedX(type->RleSprite,frame&127,x,y);
@@ -939,14 +950,18 @@ local int PointToPointMissile(Missile* missile)
 global void MissileHit(const Missile* missile)
 {
     Unit* goal;
+    int x;
+    int y;
 
     // FIXME: should I move the PlayMissileSound to here?
 
     if( missile->Type->ImpactSound.Sound ) {
 	PlayMissileSound(missile,missile->Type->ImpactSound.Sound);
     }
+    x=missile->X+missile->Type->Width/2;
+    y=missile->Y+missile->Type->Height/2;
     if( missile->Type->ImpactMissile ) {
-	MakeMissile(missile->Type->ImpactMissile,missile->X,missile->Y,0,0);
+	MakeMissile(missile->Type->ImpactMissile,x,y,0,0);
     }
     if( !missile->SourceType ) {	// no target
 	return;
@@ -955,21 +970,19 @@ global void MissileHit(const Missile* missile)
     // FIXME: must choose better goal!
     // FIXME: what can the missile hit?
     // FIXME: "missile-catapult-rock", "missile-ballista-bolt", have are effect
-    goal=UnitOnMapTile(missile->X/TileSizeX,missile->Y/TileSizeY);
-    if( !goal || !goal->HP ) {
-	int dx;
-	int dy;
 
-	dx=missile->X/TileSizeX;
-	dy=missile->Y/TileSizeY;
-	if( WallOnMap(dx,dy) ) {
+    x/=TileSizeX;
+    y/=TileSizeY;
+    goal=UnitOnMapTile(x,y);
+    if( !goal || !goal->HP ) {
+	if( WallOnMap(x,y) ) {
 	    DebugLevel3("Missile on wall?\n");
 	    // FIXME: don't use UnitTypeByIdent here, this is slow!
-	    if( HumanWallOnMap(dx,dy) ) {
-		HitWall(dx,dy,CalculateDamageStats(missile->SourceStats,
+	    if( HumanWallOnMap(x,y) ) {
+		HitWall(x,y,CalculateDamageStats(missile->SourceStats,
 			UnitTypeByIdent("unit-human-wall")->Stats));
 	    } else {
-		HitWall(dx,dy,CalculateDamageStats(missile->SourceStats,
+		HitWall(x,y,CalculateDamageStats(missile->SourceStats,
 			UnitTypeByIdent("unit-orc-wall")->Stats));
 	    }
 	    return;
@@ -1055,7 +1068,7 @@ global void MissileActions(void)
 			    missile->DY+=missile->Ystep*TileSizeY*2;
 			    MissileHit(missile);
 			    // FIXME: hits to left and right
-			    // FIXME: reduce damage effect
+			    // FIXME: reduce damage effects on later impacts
 			    break;
 			default:
 			    missile->Type=MissileFree;
@@ -1122,11 +1135,54 @@ global void MissileActions(void)
 			break;
 		}
 		break;
+
+	    case MissileClassFire:
+		missile->Wait=missile->Type->Speed;
+		if( ++missile->Frame==missile->Type->RleSprite->NumFrames ) {
+		    int f;
+		    Unit* unit;
+
+		    unit=missile->SourceUnit;
+		    if( unit->Destroyed || !unit->HP ) {
+#ifdef NEW_UNIT
+			if( !--unit->Refs ) {
+			    ReleaseUnit(unit);
+			}
+#endif
+			missile->Type=MissileFree;
+			break;
+		    }
+		    missile->Frame=0;
+		    f=(100*unit->HP)/unit->Stats->HitPoints;
+		    if( f>75) {
+			missile->Type=MissileFree;	// No fire for this
+			unit->Burning=0;
+		    } else if( f>50 ) {
+			if( missile->Type!=MissileTypeSmallFire ) {
+			    missile->X+=missile->Type->Width/2;
+			    missile->Y+=missile->Type->Height/2;
+			    missile->Type=MissileTypeSmallFire;
+			    missile->X-=missile->Type->Width/2;
+			    missile->Y-=missile->Type->Height/2;
+			}
+		    } else {
+			if( missile->Type!=MissileTypeBigFire ) {
+			    missile->X+=missile->Type->Width/2;
+			    missile->Y+=missile->Type->Height/2;
+			    missile->Type=MissileTypeBigFire;
+			    missile->X-=missile->Type->Width/2;
+			    missile->Y-=missile->Type->Height/2;
+			}
+		    }
+		}
+		break;
+
 	}
 
 	if (missile->Type!=MissileFree && MissileVisible(missile)) {
 	    // check after movement
 	    MustRedraw|=RedrawMap;
+	    // FIXME: must mark the exact tile, for more optimazation
 	}
     }
 }
@@ -1141,8 +1197,8 @@ global int ViewPointDistanceToMissile(const Missile* missile)
     int x;
     int y;
 
-    x=missile->X/TileSizeX;
-    y=missile->Y/TileSizeY;		// pixel -> tile
+    x=(missile->X+missile->Type->Width/2)/TileSizeX;
+    y=(missile->Y+missile->Type->Height/2)/TileSizeY;	// pixel -> tile
 
     DebugLevel3(__FUNCTION__": Missile %p at %d %d\n",missile,x,y);
 
diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp
index e17a4315c..2c69c1803 100644
--- a/src/unit/unit.cpp
+++ b/src/unit/unit.cpp
@@ -2505,6 +2505,41 @@ global void HitUnit(Unit* unit,int damage)
 		,0,0);
     }
 #endif
+    if( type->Building && !unit->Burning ) {
+	int f;
+	Missile* missile;
+
+	f=(100*unit->HP)/unit->Stats->HitPoints;
+	if( f>75) {
+	    ; // No fire for this
+	} else if( f>50 ) {
+	    missile=MakeMissile(MissileTypeByIdent("missile-small-fire")
+		    ,unit->X*TileSizeX
+			    +(type->TileWidth*TileSizeX)/2
+		    ,unit->Y*TileSizeY
+			    +(type->TileHeight*TileSizeY)/2
+			    -TileSizeY
+		    ,0,0);
+	    missile->SourceUnit=unit;
+	    unit->Burning=1;
+#ifdef NEW_UNIT
+	    ++unit->Refs;
+#endif
+	} else {
+	    missile=MakeMissile(MissileTypeByIdent("missile-big-fire")
+		    ,unit->X*TileSizeX
+			    +(type->TileWidth*TileSizeX)/2
+		    ,unit->Y*TileSizeY
+			    +(type->TileHeight*TileSizeY)/2
+			    -TileSizeY
+		    ,0,0);
+	    missile->SourceUnit=unit;
+	    unit->Burning=1;
+#ifdef NEW_UNIT
+	    ++unit->Refs;
+#endif
+	}
+    }
 
     if( unit->Command.Action!=UnitActionStill ) {
 	return;