* added some comments
authorsheepluva
Sat, 01 May 2010 05:15:16 +0000
changeset 3384 7eb4707d43f0
parent 3383 45a73be4d8c1
child 3385 361bd29293f4
* added some comments * added some nil checks * removed unused and incorrect _0_998 * added sine-gun (early alpha)
QTfrontend/hwconsts.cpp.in
hedgewars/GSHandlers.inc
hedgewars/HHHandlers.inc
hedgewars/uAIAmmoTests.pas
hedgewars/uConsts.pas
hedgewars/uFloat.pas
hedgewars/uGears.pas
hedgewars/uLocale.pas
hedgewars/uStore.pas
share/hedgewars/Data/Graphics/AmmoMenu/Ammos.png
share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw.png
share/hedgewars/Data/Locale/en.txt
--- a/QTfrontend/hwconsts.cpp.in	Fri Apr 30 23:39:32 2010 +0000
+++ b/QTfrontend/hwconsts.cpp.in	Sat May 01 05:15:16 2010 +0000
@@ -31,10 +31,10 @@
 QStringList * mapList;
 
 QString * cDefaultAmmoStore = new QString(
-        "93919294221991210322351110012010000002111909"
-        "04050405416006555465544647765766666661555010"
-        "00000000000002055000000400070040000000002000"
-        "13111103121111111231141111111111111112111011"
+        "939192942219912103223511100120100000021119091"
+        "040504054160065554655446477657666666615550100"
+        "000000000000020550000004000700400000000020000"
+        "131111031211111112311411111111111111121110111"
 		);
 int cAmmoNumber = cDefaultAmmoStore->size() / 4;
 
@@ -42,30 +42,30 @@
 	QList< QPair<QString, QString> >()
 	<< qMakePair(QString("Default"), *cDefaultAmmoStore)
 	<< qMakePair(QString("Crazy"),     QString(
-        "99999999999999999929999999999999992999999099" // TODO: Remove Piano's unlimited uses!
-        "11111101111111111111111111111111111111111111"
-        "00000000000000000000000000000000000000000000"
-        "13111103121111111231141111111111111112111001"))
+        "999999999999999999299999999999999929999990999" // TODO: Remove Piano's unlimited uses!
+        "111111011111111111111111111111111111111111111"
+        "000000000000000000000000000000000000000000000"
+        "131111031211111112311411111111111111121110010"))
 	<< qMakePair(QString("Pro mode"),  QString(
-        "90900090000000000000090000000000000000000009"
-        "00000000000000000000000000000000000000000000"
-        "00000000000002055000000400070040000000002000"
-        "11111111111111111111111111111111111111111001"))
+        "909000900000000000000900000000000000000000090"
+        "000000000000000000000000000000000000000000000"
+        "000000000000020550000004000700400000000020000"
+        "111111111111111111111111111111111111111110011"))
 	<< qMakePair(QString("Shoppa"),    QString(
-        "00000099000000000000000000000000000000000000"
-        "44444100442444022101121212224220000000020004"
-        "00000000000000000000000000000000000000000000"
-        "11111111111111111111111111111111111111111011"))
+        "000000990000000000000000000000000000000000000"
+        "444441004424440221011212122242200000000200040"
+        "000000000000000000000000000000000000000000000"
+        "111111111111111111111111111111111111111110111"))
 	<< qMakePair(QString("Basketball"),QString(
-		"00000090000009000000000000000000000000000000"
-		"00000000000000000000000000000000000000000000"
-		"00000000000000055000000400070040000000002000"
-		"11111111111111111111111111111111111111111111"))
+		"000000900000090000000000000000000000000000000"
+		"000000000000000000000000000000000000000000000"
+		"000000000000000550000004000700400000000020000"
+		"111111111111111111111111111111111111111111111"))
 	<< qMakePair(QString("Minefield"), QString(
-		"00000099000900000003000000000000000000000000"
-		"00000000000000000000000000000000000000000000"
-		"00000000000002055000000400070040000000002000"
-		"11111111111111111111111111111111111111111111"))
+		"000000990009000000030000000000000000000000000"
+		"000000000000000000000000000000000000000000000"
+		"000000000000020550000004000700400000000020000"
+		"111111111111111111111111111111111111111111111"))
 	;
 
 QColor * color1 = new QColor(221,   0,   0);
--- a/hedgewars/GSHandlers.inc	Fri Apr 30 23:39:32 2010 +0000
+++ b/hedgewars/GSHandlers.inc	Sat May 01 05:15:16 2010 +0000
@@ -73,7 +73,7 @@
         CheckGearDrowning:= true;
         Gear^.State:= gstDrowning;
         Gear^.RenderTimer:= false;
-        if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot) and (Gear^.Kind <> gtDEagleShot) then
+        if (Gear^.Kind <> gtSniperRifleShot) and (Gear^.Kind <> gtShotgunShot) and (Gear^.Kind <> gtDEagleShot) and (Gear^.Kind <> gtSineGunShot) then
           Gear^.doStep:= @doStepDrowningGear;
         if Gear^.Kind = gtHedgehog then
             begin
@@ -3109,3 +3109,141 @@
 else
     Gear^.dY:= Gear^.dY + cGravity * 2; // let it fall faster so itdoesn't take too long for the whole attack
 end;
+
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSineGunShotWork(Gear: PGear);
+var x, y, rX, rY, t, tmp, initHealth: LongWord;
+    oX, oY, ldX, ldY, sdX, sdY, sine, lx, ly, amp: hwFloat;
+    justCollided: boolean;
+begin
+AllInactive:= false;
+initHealth:= Gear^.Health;
+lX:= Gear^.X;
+lY:= Gear^.Y;
+ldX:= Gear^.dX;
+ldY:= Gear^.dY;
+sdy:= _0_5/Distance(Gear^.dX,Gear^.dY);
+ldX:= ldX * sdy;
+ldY:= ldY * sdy;
+sdY:= hwAbs(ldX) + hwAbs(ldY);
+sdX:= _1 - hwAbs(ldX/sdY);
+sdY:= _1 - hwAbs(ldY/sdY);
+if (ldX.isNegative = ldY.isNegative) then sdY:= -sdY;
+
+// initial angle depends on current GameTicks
+t:= GameTicks mod 4096;
+
+
+// used for a work-around detection of area that is within land array, but outside borders
+justCollided:= false;
+
+repeat
+    lX:= lX + ldX;
+    lY:= lY + ldY;
+    oX:= Gear^.X;
+    oY:= Gear^.Y;
+    rX:= hwRound(oX);
+    rY:= hwRound(oY);
+    tmp:= t mod 4096;
+    amp:= _128 * (_1 - hwSqr(int2hwFloat(Gear^.Health)/initHealth));
+    sine:= amp * AngleSin(tmp mod 2048);
+    sine.isNegative:= (tmp < 2048);
+    inc(t,Gear^.Health div 313);
+    Gear^.X:= lX + (sine * sdX);
+    Gear^.Y:= ly + (sine * sdY);
+    Gear^.dX:= Gear^.X - oX;
+    Gear^.dY:= Gear^.Y - oY;
+    
+    x:= hwRound(Gear^.X);
+    y:= hwRound(Gear^.Y);
+    
+    // if borders are on, stop outside land array
+    if hasBorder and (((x and LAND_WIDTH_MASK) <> 0) or ((y and LAND_HEIGHT_MASK) <> 0)) then
+            begin
+            Gear^.Damage:= 0;
+            Gear^.Health:= 0;
+            end
+    else
+        begin
+        if (rY <= cWaterLine) or (y <= cWaterLine) then
+            begin
+            if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0)
+                and (Land[y, x] <> 0) then
+                    begin
+                    if justCollided then
+                        begin
+                        Gear^.Damage:= 0;
+                        Gear^.Health:= 0;
+                        end
+                    else
+                        begin
+                        inc(Gear^.Damage,3);
+                        justCollided:= true;
+                        end;
+                    end
+                else
+                    justCollided:= false;
+
+        // kick nearby hogs, dig tunnel and add some fire
+        // if at least 5 collisions occured
+        if Gear^.Damage > 0 then
+            begin
+            DrawExplosion(rX,rY,Gear^.Radius);
+            
+            // kick nearby hogs
+            AmmoShove(Gear, 35, 50);
+            
+            dec(Gear^.Health, Gear^.Damage);
+            Gear^.Damage:= 0;
+            
+            // add some fire to the tunnel
+            if getRandom(6) = 0 then
+                AddGear(x-Gear^.Radius+getRandom(2*Gear^.Radius), y-getRandom(Gear^.Radius+1), gtFlame, gsttmpFlag, _0, _0, 0);
+            end;
+
+        if getRandom(100) = 0 then
+            AddGear(x, y, gtSmokeTrace, 0, _0, _0, 0);
+        
+        end
+        // if underwater get additional damage
+        else dec(Gear^.Health, 5);
+    end;
+
+    dec(Gear^.Health);
+    
+    // decrease bullet size towards the end
+    if (Gear^.Radius > 4) then begin 
+        if (Gear^.Health <= (initHealth div 3)) then dec(Gear^.Radius) end
+    else if (Gear^.Radius > 3) then begin
+        if (Gear^.Health <= (initHealth div 4)) then dec(Gear^.Radius) end
+    else if (Gear^.Radius > 2) then begin
+        if (Gear^.Health <= (initHealth div 5)) then dec(Gear^.Radius) end
+    else if (Gear^.Radius > 1) then begin
+        if (Gear^.Health <= (initHealth div 6)) then dec(Gear^.Radius) end;
+
+until (Gear^.Health <= 0);
+
+DeleteGear(Gear);
+AfterAttack;
+end;
+
+procedure doStepSineGunShot(Gear: PGear);
+var HHGear: PGear;
+begin
+PlaySound(sndSineGun);
+
+
+// push the shooting Hedgehog back
+HHGear:= CurrentHedgehog^.Gear;
+Gear^.dX.isNegative:= not Gear^.dX.isNegative;
+Gear^.dY.isNegative:= not Gear^.dY.isNegative;
+HHGear^.dX:= Gear^.dX;
+HHGear^.dY:= Gear^.dY;
+AmmoShove(Gear, 0, 80);
+Gear^.dX.isNegative:= not Gear^.dX.isNegative;
+Gear^.dY.isNegative:= not Gear^.dY.isNegative;
+
+Gear^.doStep:= @doStepSineGunShotWork
+
+end;
--- a/hedgewars/HHHandlers.inc	Fri Apr 30 23:39:32 2010 +0000
+++ b/hedgewars/HHHandlers.inc	Sat May 01 05:15:16 2010 +0000
@@ -155,6 +155,7 @@
                          amRope: CurAmmoGear:= AddGear(hwRound(Gear^.X), hwRound(Gear^.Y), gtRope, 0, xx, yy, 0);
                          amMine: AddGear(hwRound(X) + hwSign(dX) * 7, hwRound(Y), gtMine, gstWait, SignAs(_0_02, dX), _0, 3000);
                        amDEagle: CurAmmoGear:= AddGear(hwRound(X + xx * cHHRadius), hwRound(Y + yy * cHHRadius), gtDEagleShot, 0, xx * _0_5, yy * _0_5, 0);
+                      amSineGun: CurAmmoGear:= AddGear(hwRound(X + xx * cHHRadius), hwRound(Y + yy * cHHRadius), gtSineGunShot, 0, xx * _0_5, yy * _0_5, 0);
                   amSniperRifle: begin
                                  PlaySound(sndSniperReload);
                                  CurAmmoGear:= AddGear(hwRound(X + xx * cHHRadius), hwRound(Y + yy * cHHRadius), gtSniperRifleShot, 0, xx * _0_5, yy * _0_5, 0);
--- a/hedgewars/uAIAmmoTests.pas	Fri Apr 30 23:39:32 2010 +0000
+++ b/hedgewars/uAIAmmoTests.pas	Sat May 01 05:15:16 2010 +0000
@@ -95,7 +95,8 @@
             (proc: nil;              flags: 0), // amBirdy
             (proc: nil;              flags: 0), // amPortalGun
             (proc: nil;              flags: 0), // amPiano
-            (proc: @TestGrenade;     flags: 0)  // amGasBomb
+            (proc: @TestGrenade;     flags: 0), // amGasBomb
+            (proc: @TestShotgun;     flags: 0)  // amSineGun
             );
 
 const BadTurn = Low(LongInt) div 4;
--- a/hedgewars/uConsts.pas	Fri Apr 30 23:39:32 2010 +0000
+++ b/hedgewars/uConsts.pas	Sat May 01 05:15:16 2010 +0000
@@ -72,8 +72,9 @@
             sprHandGrenade, sprHandMelon, sprHandMortar, sprHandSkip, sprHandCluster,
             sprHandDynamite, sprHandHellish, sprHandMine, sprHandSeduction, sprHandVamp,
             sprBigExplosion, sprSmokeRing, sprBeeTrace, sprEgg, sprTargetBee, sprHandBee, 
-            sprFeather, sprPiano);
-
+            sprFeather, sprPiano, sprHandSineGun);
+    
+    // Gears that interact with other Gears and/or Land
     TGearType = (gtAmmo_Bomb, gtHedgehog, gtAmmo_Grenade, gtHealthTag, // 3
             gtGrave, gtBee, gtShotgunShot, gtPickHammer, gtRope, // 8
             gtSmokeTrace, gtExplosion, gtMine, gtCase, gtDEagleShot, gtDynamite, // 14
@@ -84,8 +85,9 @@
             gtWhip, gtKamikaze, gtCake, gtSeduction, gtWatermelon, gtMelonPiece, // 37
             gtHellishBomb, gtEvilTrace, gtWaterUp, gtDrill, gtBallGun, gtBall,gtRCPlane,
             gtSniperRifleShot, gtJetpack, gtMolotov, gtExplosives, gtBirdy, 
-            gtBigExplosion, gtEgg, gtPortal, gtPortalGun, gtPiano, gtGasBomb);
+            gtBigExplosion, gtEgg, gtPortal, gtPortalGun, gtPiano, gtGasBomb, gtSineGunShot);
 
+    // Gears that are _only_ of visual nature (e.g. background stuff, visual effects, speechbubbles, etc.)
     TVisualGearType = (vgtFlake, vgtCloud, vgtExplPart, vgtExplPart2, vgtFire,
             vgtSmallDamageTag, vgtTeamHealthSorter, vgtSpeechBubble, vgtBubble,
             vgtSteam, vgtAmmo, vgtSmoke, vgtSmokeWhite, vgtHealth, vgtShell,
@@ -114,7 +116,7 @@
             sndMelonImpact, sndDroplet1, sndDroplet2, sndDroplet3, sndEggBreak, sndDrillRocket,
             sndPoisonCough, sndPoisonMoan, sndBirdyLay, sndWhistle, sndBeeWater,
             sndPiano0, sndPiano1, sndPiano2, sndPiano3, sndPiano4, sndPiano5, sndPiano6, sndPiano7, sndPiano8,
-            sndSkip);
+            sndSkip, sndSineGun);
 
     TAmmoType  = (amNothing, amGrenade, amClusterBomb, amBazooka, amBee, amShotgun, amPickHammer,
             amSkip, amRope, amMine, amDEagle, amDynamite, amFirePunch, amWhip,
@@ -123,7 +125,7 @@
             amSeduction, amWatermelon, amHellishBomb, amNapalm, amDrill, amBallgun,
             amRCPlane, amLowGravity, amExtraDamage, amInvulnerable, amExtraTime,
             amLaserSight, amVampiric, amSniperRifle, amJetpack, amMolotov, amBirdy, amPortalGun,
-            amPiano, amGasBomb);
+            amPiano, amGasBomb, amSineGun);
 
     THWFont = (fnt16, fntBig, fntSmall, CJKfnt16, CJKfntBig, CJKfntSmall);
 
@@ -739,7 +741,9 @@
             (FileName:  'Feather'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
             Width:  15; Height: 25; imageWidth: 0; imageHeight: 0; saveSurf: false), // sprFeather
             (FileName:  'Piano'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
-            Width:  128; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false) // sprPiano
+            Width:  128; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false), // sprPiano
+            (FileName:  'amSineGun'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false) // sprHandSineGun
             );
 
     Wavez: array [TWave] of record
@@ -860,7 +864,8 @@
             (FileName:                  'egg.ogg'; Path: ptSounds),// sndPiano6
             (FileName:                  'egg.ogg'; Path: ptSounds),// sndPiano7
             (FileName:                  'egg.ogg'; Path: ptSounds),// sndPiano8
-            (FileName:                 'skip.ogg'; Path: ptSounds) // sndSkip
+            (FileName:                 'skip.ogg'; Path: ptSounds),// sndSkip
+            (FileName:          'shotgunfire.ogg'; Path: ptSounds) // sndSineGun
             );
 
     Ammoz: array [TAmmoType] of record
@@ -896,6 +901,8 @@
             SkipTurns: 9999;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Grenade
             (NameId: sidGrenade;
             NameTex: nil;
             Probability: 0;
@@ -916,6 +923,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// ClusterBomb
             (NameId: sidClusterBomb;
             NameTex: nil;
             Probability: 100;
@@ -936,6 +945,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Bazooka
             (NameId: sidBazooka;
             NameTex: nil;
             Probability: 0;
@@ -956,6 +967,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Bee
             (NameId: sidBee;
             NameTex: nil;
             Probability: 100;
@@ -976,6 +989,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Shotgun
             (NameId: sidShotgun;
             NameTex: nil;
             Probability: 0;
@@ -996,6 +1011,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// PickHammer
             (NameId: sidPickHammer;
             NameTex: nil;
             Probability: 0;
@@ -1016,6 +1033,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Skip
             (NameId: sidSkip;
             NameTex: nil;
             Probability: 0;
@@ -1036,6 +1055,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Rope
             (NameId: sidRope;
             NameTex: nil;
             Probability: 100;
@@ -1060,6 +1081,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Mine
             (NameId: sidMine;
             NameTex: nil;
             Probability: 100;
@@ -1080,6 +1103,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// DEagle
             (NameId: sidDEagle;
             NameTex: nil;
             Probability: 20;
@@ -1100,6 +1125,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Dynamite
             (NameId: sidDynamite;
             NameTex: nil;
             Probability: 100;
@@ -1120,6 +1147,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// FirePunch
             (NameId: sidFirePunch;
             NameTex: nil;
             Probability: 0;
@@ -1140,6 +1169,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Whip
             (NameId: sidWhip;
             NameTex: nil;
             Probability: 0;
@@ -1160,6 +1191,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// BaseballBat
             (NameId: sidBaseballBat;
             NameTex: nil;
             Probability: 100;
@@ -1180,6 +1213,8 @@
             SkipTurns: 2;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Parachute
             (NameId: sidParachute;
             NameTex: nil;
             Probability: 100;
@@ -1206,6 +1241,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// AirAttack
             (NameId: sidAirAttack;
             NameTex: nil;
             Probability: 100;
@@ -1230,6 +1267,8 @@
             SkipTurns: 5;
             PosCount: 2;
             PosSprite: sprAmAirplane),
+
+// MineStrike
             (NameId: sidMineStrike;
             NameTex: nil;
             Probability: 200;
@@ -1254,6 +1293,8 @@
             SkipTurns: 5;
             PosCount: 2;
             PosSprite: sprAmAirplane),
+
+// BlowTorch
             (NameId: sidBlowTorch;
             NameTex: nil;
             Probability: 100;
@@ -1274,6 +1315,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Girder
             (NameId: sidGirder;
             NameTex: nil;
             Probability: 150;
@@ -1298,6 +1341,8 @@
             SkipTurns: 0;
             PosCount: 8;
             PosSprite: sprAmGirder),
+
+// Teleport
             (NameId: sidTeleport;
             NameTex: nil;
             Probability: 200;
@@ -1323,6 +1368,8 @@
             SkipTurns: 0;
             PosCount: 2;
             PosSprite: sprAmTeleport),
+
+// Switch
             (NameId: sidSwitch;
             NameTex: nil;
             Probability: 100;
@@ -1347,6 +1394,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Mortar
             (NameId: sidMortar;
             NameTex: nil;
             Probability: 100;
@@ -1367,6 +1416,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Kamikaze
             (NameId: sidKamikaze;
             NameTex: nil;
             Probability: 100;
@@ -1387,6 +1438,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Cake
             (NameId: sidCake;
             NameTex: nil;
             Probability: 100;
@@ -1407,6 +1460,8 @@
             SkipTurns: 4;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Seduction
             (NameId: sidSeduction;
             NameTex: nil;
             Probability: 100;
@@ -1427,6 +1482,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Watermelon
             (NameId: sidWatermelon;
             NameTex: nil;
             Probability: 400;
@@ -1447,6 +1504,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// HellishBomb ("Hellish Hand-Grenade")
             (NameId: sidHellishBomb;
             NameTex: nil;
             Probability: 400;
@@ -1467,6 +1526,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Napalm
             (NameId: sidNapalm;
             NameTex: nil;
             Probability: 100;
@@ -1491,6 +1552,8 @@
             SkipTurns: 7;
             PosCount: 2;
             PosSprite: sprAmAirplane),
+
+// Drill ("Drill Rocket")
             (NameId: sidDrill;
             NameTex: nil;
             Probability: 300;
@@ -1511,6 +1574,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprDrill),
+
+// Ballgun
             (NameId: sidBallgun;
             NameTex: nil;
             Probability: 400;
@@ -1531,6 +1596,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// RC-Plane
             (NameId: sidRCPlane;
             NameTex: nil;
             Probability: 200;
@@ -1553,6 +1620,8 @@
             SkipTurns: 4;
             PosCount: 1;
             PosSprite: sprWater),
+
+// LowGravity
             (NameId: sidLowGravity;
             NameTex: nil;
             Probability: 20;
@@ -1578,6 +1647,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// ExtraDamage
             (NameId: sidExtraDamage;
             NameTex: nil;
             Probability: 15;
@@ -1603,6 +1674,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Invulnerable
             (NameId: sidInvulnerable;
             NameTex: nil;
             Probability: 20;
@@ -1628,6 +1701,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// ExtraTime
             (NameId: sidExtraTime;
             NameTex: nil;
             Probability: 30;
@@ -1653,6 +1728,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// LaserSight
             (NameId: sidLaserSight;
             NameTex: nil;
             Probability: 15;
@@ -1678,6 +1755,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Vampiric
             (NameId: sidVampiric;
             NameTex: nil;
             Probability: 15;
@@ -1703,6 +1782,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// SniperRifle
             (NameId: sidSniperRifle;
             NameTex: nil;
             Probability: 20;
@@ -1723,6 +1804,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Jetpack ("Flying Saucer")
             (NameId: sidJetpack;
             NameTex: nil;
             Probability: 20;
@@ -1749,6 +1832,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Molotov
             (NameId: sidMolotov;
             NameTex: nil;
             Probability: 0;
@@ -1769,6 +1854,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Birdy
             (NameId: sidBirdy;
             NameTex: nil;
             Probability: 20;
@@ -1791,6 +1878,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// PortalGun
             (NameId: sidPortalGun;
             NameTex: nil;
             Probability: 20;
@@ -1813,6 +1902,8 @@
             SkipTurns: 0;
             PosCount: 1;
             PosSprite: sprWater),
+
+// Piano
             (NameId: sidPiano;
             NameTex: nil;
             Probability: 100;
@@ -1837,6 +1928,8 @@
             SkipTurns: 7;
             PosCount: 1;
             PosSprite: sprWater),
+
+// GasBomb
             (NameId: sidGasBomb;
             NameTex: nil;
             Probability: 0;
@@ -1856,6 +1949,28 @@
             isDamaging: true;
             SkipTurns: 0;
             PosCount: 1;
+            PosSprite: sprWater),
+            
+// SineGun
+            (NameId: sidSineGun;
+            NameTex: nil;
+            Probability: 20;
+            NumberInCase: 2;
+            Ammo: (Propz: ammoprop_AttackInMove;
+                Count: 1;
+                InitialCount: 1;
+                NumPerTurn: 0;
+                Timer: 0;
+                Pos: 0;
+                AmmoType: amSineGun;
+                AttackVoice: sndNone);
+            Slot: 2;
+            TimeAfterTurn: 0;
+            minAngle: 0;
+            maxAngle: 0;
+            isDamaging: true;
+            SkipTurns: 0;
+            PosCount: 1;
             PosSprite: sprWater)
             );
 
--- a/hedgewars/uFloat.pas	Fri Apr 30 23:39:32 2010 +0000
+++ b/hedgewars/uFloat.pas	Sat May 01 05:15:16 2010 +0000
@@ -105,7 +105,6 @@
            _0_93: hwFloat = (isNegative: false; QWordValue:  3994319585);
            _0_96: hwFloat = (isNegative: false; QWordValue:  4123168604);
           _0_995: hwFloat = (isNegative: false; QWordValue:  4273492459);
-          _0_998: hwFloat = (isNegative: false; QWordValue:  4294967296);
           _0_999: hwFloat = (isNegative: false; QWordValue:  4290672328);
             _1_9: hwFloat = (isNegative: false; QWordValue:  8160437862);
               _0: hwFloat = (isNegative: false; QWordValue:           0);
--- a/hedgewars/uGears.pas	Fri Apr 30 23:39:32 2010 +0000
+++ b/hedgewars/uGears.pas	Sat May 01 05:15:16 2010 +0000
@@ -186,7 +186,8 @@
             @doStepPortal,
             @doStepPortalGun,
             @doStepPiano,
-            @doStepBomb
+            @doStepBomb,
+            @doStepSineGunShot
             );
 
 procedure InsertGearToList(Gear: PGear);
@@ -482,6 +483,10 @@
        gtPiano: begin
                 gear^.Radius:= 32
                 end;
+ gtSineGunShot: begin
+                gear^.Radius:= 5;
+                gear^.Health:= 6000;
+                end;
      end;
 InsertGearToList(gear);
 AddGear:= gear;
@@ -1280,6 +1285,7 @@
             amRope: DrawRotated(sprHandRope, hx, hy, hwSign(Gear^.dX), aangle);
             amShotgun: DrawRotated(sprHandShotgun, hx, hy, hwSign(Gear^.dX), aangle);
             amDEagle: DrawRotated(sprHandDEagle, hx, hy, hwSign(Gear^.dX), aangle);
+            amSineGun: DrawRotated(sprHandShotgun, hx, hy, hwSign(Gear^.dX), aangle);
             amSniperRifle: DrawRotatedF(sprSniperRifle, hx, hy, 0, hwSign(Gear^.dX), aangle);
             amBlowTorch: DrawRotated(sprHandBlowTorch, hx, hy, hwSign(Gear^.dX), aangle);
             amCake: DrawRotated(sprHandCake, hx, hy, hwSign(Gear^.dX), aangle);
--- a/hedgewars/uLocale.pas	Fri Apr 30 23:39:32 2010 +0000
+++ b/hedgewars/uLocale.pas	Sat May 01 05:15:16 2010 +0000
@@ -29,7 +29,7 @@
             sidHellishBomb, sidDrill, sidBallgun, sidNapalm, sidRCPlane,
             sidLowGravity, sidExtraDamage, sidInvulnerable, sidExtraTime,
             sidLaserSight, sidVampiric, sidSniperRifle, sidJetpack,
-            sidMolotov, sidBirdy, sidPortalGun, sidPiano, sidGasBomb);
+            sidMolotov, sidBirdy, sidPortalGun, sidPiano, sidGasBomb, sidSineGun);
 
     TMsgStrId = (sidStartFight, sidDraw, sidWinner, sidVolume, sidPaused,
             sidConfirm, sidSuddenDeath, sidRemaining, sidFuel, sidSync,
--- a/hedgewars/uStore.pas	Fri Apr 30 23:39:32 2010 +0000
+++ b/hedgewars/uStore.pas	Sat May 01 05:15:16 2010 +0000
@@ -453,7 +453,9 @@
 for ai:= Low(TAmmoType) to High(TAmmoType) do
     with Ammoz[ai] do
         begin
+        TryDo(trAmmo[NameId] <> '','No default text/translation found for ammo type #' + intToStr(ord(ai)) + '!',true);
         tmpsurf:= TTF_RenderUTF8_Blended(Fontz[CheckCJKFont(trAmmo[NameId],fnt16)].Handle, Str2PChar(trAmmo[NameId]), cWhiteColorChannels);
+        TryDo(tmpsurf <> nil,'Name-texture creation for ammo type #' + intToStr(ord(ai)) + ' failed!',true);
         tmpsurf:= doSurfaceConversion(tmpsurf);
         NameTex:= Surface2Tex(tmpsurf, false);
         SDL_FreeSurface(tmpsurf)
Binary file share/hedgewars/Data/Graphics/AmmoMenu/Ammos.png has changed
Binary file share/hedgewars/Data/Graphics/AmmoMenu/Ammos_bw.png has changed
--- a/share/hedgewars/Data/Locale/en.txt	Fri Apr 30 23:39:32 2010 +0000
+++ b/share/hedgewars/Data/Locale/en.txt	Sat May 01 05:15:16 2010 +0000
@@ -45,6 +45,7 @@
 00:42=Portable Portal Device
 00:43=Piano Strike
 00:44=Gas grenade
+00:45=Sine Gun
 
 01:00=Let's fight!
 01:01=Round draw