merge
authorsheepluva
Sat, 29 Apr 2017 23:49:39 +0200
changeset 12384 1adc078355d1
parent 12383 e3d9abcc427a (current diff)
parent 12382 95fc84a9837e (diff)
child 12385 24f8d3ec88a1
merge
--- a/ChangeLog.txt	Sat Apr 29 23:45:14 2017 +0200
+++ b/ChangeLog.txt	Sat Apr 29 23:49:39 2017 +0200
@@ -57,6 +57,7 @@
  * Fix invalid girder placement costing energy
  * Special tools like structure placer now have their own proper descriptions (instead of Air Attack description, etc.)
  * Costs for weapon and utility crates were all equal
+ * Remove airplane cursor
  * Many other fixes and tweaks
 
 Racer and TechRacer:
@@ -67,6 +68,8 @@
   + waypointradius: Size of waypoints
   + maxwaypoints: Maximum allowed number of waypoints
  + Show correct ranking and times in stats screen of Racer and TechRacer
+ * Fix description and icon of waypoint placement tool in Racer
+ * Remove airplane cursor in Racer
  * Fixed waypoint message in TechRacer and Racer overwriting current weapon selection message
  * Fixed TechRacer not recording finish if time was >= 100s
 
@@ -158,6 +161,7 @@
  * Fix error when trying to set ShoppaBalance rank without anything selected
  * Don't show misleading circle when placing girder/rubber
  * Disable timer keys 2-4 in rubber placement mode
+ * Fix incorrect weapon crate preview of air attack, drill strike and napalm
 
 Other Game Styles:
  + Capture The Flag supports setting number of captures with script parameter “capture=<number>”
@@ -166,23 +170,45 @@
  * Mutant script shows now appropriate ranking and graph in stats screen
  * Disable Sudden Death for good in Shoppa game scheme, some game styles and mission maps
 
-Missions and Campaigns:
+A Classic Fairytale:
+ + Mission 3: Improved mission panel texts to clarify the goals at all time
+ + Mission 4: Add infinite skip
+ + Mission 6: Add alternate dialogues when killing cyborgs before collecting the crates
+ + All missions: Clarify mine timers
+ * Mission 2: Fix crash when trying to open ammo menu in opening sequence
+ * Mission 3: Fix various Lua errors when playing with 2 hogs and one of them dies
+ * Mission 3: Fix broken end sequence after killing cyborg or princess
+ * Mission 5: Fix crash when skipping animation while the cyborg talks before the 3rd wave of cannibals starts
+ * Mission 6: Block off left cave entrance to stop player to just rope all the way around
+ * Mission 6: Remove some misleading mission panel texts
+ * Mission 8: Fix Lua error message at the beginning
+ * Mission 10: Fix mission becoming unplayable when all hogs except the traitor died
+ * All missions: Add missing texts for translation
+ * Fix swapped mission preview images of missions 2 and 3
+
+A Space Adventure:
+ + A few campaign missions now save your personal best successes (e.g. fastest finish in Hard Flying) which get shown after you finish them agin
+ + Add skip to a few missions where it doesn't hurt
+ + Menu: Show 2 flowers over fully completed planets (with side missions)
+ * Hard Flying: Fix ending in a Lua error
+ * The First Stop: Fix stats screen showing teams twice
+ * Killing The Specialists: Fix killing hog with Deagle gave you chance to use another weapon in same turn
+ * Fix weird behaviour when walking right before the first animation in most missions
+ * Fix a coupe of texts being untranslatable
+ * Fix typos
+
+Missions:
  + New scenario: Teamwork 2
  + New scenario: Big Armory
  + New training: Basic Flying Saucer Training
  + Rope-Knocking Challenge was improved (now awards score based on kills and time; taunts for knocking out hedgehogs)
- + A Classic Fairytale, mission 6: Add alternate dialogues when killing cyborgs before collecting the crates
- + A few campaign missions now save your personal best successes (e.g. fastest finish in Hard Flying) which get shown after you finish them agin
- + A Space Adventure shows 2 flowers over fully completed planets (with side missions)
  + Rewrote some help texts in basic rope training
  + Graphical effect (black bars) while in cut scenes
- * Fix weird behaviour when walking right before the first animation in A Space Adventure missions
+ + Change description and icon for baseball bat in Knockball mission map
  * Portal Mind Challenge was cleaned up and reworked (especially less awful wording)
  * Fixed Target Practice missions getting stuck when a target dropped into water
  * Fixed mistakes and bad wording of strings in several missions, scripts and campaigns
- * Fixed Lua error message in A Classic Fairytale mission 8
  * Fixed Lua error messages and broken stats screen in Climb Home singleplayer mission
- * Fixed Killing the Specialists giving you another free turn after killing Desert Eagle with a desert eagle with shot #1-3
 
 Frontend:
  + Campaign screen shows which campaigns and missions you've completed so far
@@ -211,6 +237,7 @@
  + Themes can now have mirrored clouds and flakes: CloudsL.png, SDCloudsL.png, FlakeL.png, SDFlakeL.png
  + Water in themes supports custom animation and flow speed with water-animation and sd-water-animation in theme.cfg
  + Simplified hat format for unanimated hats; a single 32×32 image is enough. For clan hats, use size 64×32, with the color overlay at the right
+ + Ammos.png and Ammos_bw.png in HWPs are now overlayed over the base images; use transparent icons to keep them unchanged from the original
  * Default water color was black instead of blue
 
 Translations:
@@ -232,6 +259,9 @@
  + New call: SetAmmoDescriptionAppendix(ammoType, descAppend) -- Append a custom text to the description of an ammo type without overwriting it
  + New call: GetHogFort(gearUid) -- Returns the name of the fort of the hog's team
  + New call: PlaceRubber(x, y, frameIdx) -- Places a rubber
+ + New call: SendGameResultOff() -- Disable the game automatically setting a game result in the stats screen
+ + New call: SendRankingStatsOff() -- Disable the game automatically filling the team rankings in the stats screen
+ + New call: SendAchievementsStatsOff() -- Disable the game automatically populating the bullet point list in the “Details” section on the stats screen
  + New call: EndTurn([noTaunts]) -- Ends the current turn
  + New hook: onVisualGearAdd(vgUid) -- called when a visual gear is added
  + New hook: onVisualGearDelete(vgUid) -- called when a visual gear is deleted
@@ -241,6 +271,8 @@
  + New variable: AmmoTypeMax -- Maximum ammo type ID (useful to iterate through all ammo types, starting by 0)
  + Locale library: loc_noop -- Mark string for translation but don't translate it
  + Animate library: AnimInit([startAnimating]) -- New parameter startAnimating: if true, will start game in cinematic mode with most controls disabled. Must play an animation after that
+ * Fixed call: HideHog(gear) -- Fix crash when gear is invalid. Returns true on success or false otherwise
+ * Fixed call: SwitchHog(gear) -- Fix new hog being unable to open ammo menu
  * Removed call: SetAmmoStore -- Old undocumented function of questional use, has never been used
 
 0.9.21 -> 0.9.22
--- a/QTfrontend/ui/page/pagegamestats.cpp	Sat Apr 29 23:45:14 2017 +0200
+++ b/QTfrontend/ui/page/pagegamestats.cpp	Sat Apr 29 23:49:39 2017 +0200
@@ -148,6 +148,7 @@
     labelGameStats->setText("");
     healthPoints.clear();
     labelGameRank->setText("");
+    labelGameWin->setText("");
     playerPosition = 0;
     lastColor = 0;
 }
--- a/hedgewars/uGearsHandlersMess.pas	Sat Apr 29 23:45:14 2017 +0200
+++ b/hedgewars/uGearsHandlersMess.pas	Sat Apr 29 23:49:39 2017 +0200
@@ -47,7 +47,7 @@
 procedure doStepBee(Gear: PGear);
 procedure doStepShotIdle(Gear: PGear);
 procedure doStepShotgunShot(Gear: PGear);
-procedure spawnBulletTrail(Bullet: PGear);
+procedure spawnBulletTrail(Bullet: PGear; bulletX, bulletY: hwFloat);
 procedure doStepBulletWork(Gear: PGear);
 procedure doStepDEagleShot(Gear: PGear);
 procedure doStepSniperRifleShot(Gear: PGear);
@@ -1190,7 +1190,7 @@
 end;
 
 ////////////////////////////////////////////////////////////////////////////////
-procedure spawnBulletTrail(Bullet: PGear);
+procedure spawnBulletTrail(Bullet: PGear; bulletX, bulletY: hwFloat);
 var oX, oY: hwFloat;
     VGear: PVisualGear;
 begin
@@ -1212,14 +1212,14 @@
             begin
             VGear^.X:= hwFloat2Float(ox);
             VGear^.Y:= hwFloat2Float(oy);
-            VGear^.dX:= hwFloat2Float(Bullet^.X);
-            VGear^.dY:= hwFloat2Float(Bullet^.Y);
+            VGear^.dX:= hwFloat2Float(bulletX);
+            VGear^.dY:= hwFloat2Float(bulletY);
 
             // reached edge of land. assume infinite beam. Extend it way out past camera
-            if (hwRound(Bullet^.X) and LAND_WIDTH_MASK <> 0)
-            or (hwRound(Bullet^.Y) and LAND_HEIGHT_MASK <> 0) then
+            if (hwRound(bulletX) and LAND_WIDTH_MASK <> 0)
+            or (hwRound(bulletY) and LAND_HEIGHT_MASK <> 0) then
                     // only extend if not under water
-                    if not CheckCoordInWater(hwRound(Bullet^.X), hwRound(Bullet^.Y)) then
+                    if not CheckCoordInWater(hwRound(bulletX), hwRound(bulletY)) then
                         begin
                         VGear^.dX := VGear^.dX + max(LAND_WIDTH,4096) * (VGear^.dX - VGear^.X);
                         VGear^.dY := VGear^.dY + max(LAND_WIDTH,4096) * (VGear^.dY - VGear^.Y);
@@ -1231,13 +1231,14 @@
 
 procedure doStepBulletWork(Gear: PGear);
 var
-    i, x, y: LongWord;
-    oX, oY, tX, tY, cX, cY: hwFloat;
+    i, x, y, iInit: LongWord;
+    oX, oY, tX, tY, tDx, tDy: hwFloat;
     VGear: PVisualGear;
 begin
     AllInactive := false;
     inc(Gear^.Timer);
-    i := 80;
+    iInit := 80;
+    i := iInit;
     oX := Gear^.X;
     oY := Gear^.Y;
     repeat
@@ -1245,19 +1246,19 @@
         Gear^.Y := Gear^.Y + Gear^.dY;
         tX:= Gear^.X;
         tY:= Gear^.Y;
+        tDx:= Gear^.dX;
+        tDy:= Gear^.dY;
         if (Gear^.PortalCounter < 30) and WorldWrap(Gear) then
             begin
-            cX:= Gear^.X;
-            cY:= Gear^.Y;
-            Gear^.X:= tX;
-            Gear^.Y:= tY;
-            SpawnBulletTrail(Gear);
-            Gear^.X:= cX;
-            Gear^.Y:= cY;
+            DrawTunnel(oX, oY, tDx, tDy, iInit + 2 - i, 1);
+            SpawnBulletTrail(Gear, tX, tY);
+            iInit:= i;
+            oX:= Gear^.X;
+            oY:= Gear^.Y;
             inc(Gear^.PortalCounter);
             Gear^.Elasticity:= Gear^.X;
             Gear^.Friction:= Gear^.Y;
-            SpawnBulletTrail(Gear);
+            SpawnBulletTrail(Gear, Gear^.X, Gear^.Y);
             end;
         x := hwRound(Gear^.X);
         y := hwRound(Gear^.Y);
@@ -1290,7 +1291,7 @@
 
     if Gear^.Damage > 0 then
         begin
-        DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, 82 - i, 1);
+        DrawTunnel(oX, oY, Gear^.dX, Gear^.dY, iInit + 2 - i, 1);
         dec(Gear^.Health, Gear^.Damage);
         Gear^.Damage := 0
         end;
@@ -1331,7 +1332,7 @@
                     end;
                 end;
 
-            spawnBulletTrail(Gear);
+            spawnBulletTrail(Gear, Gear^.X, Gear^.Y);
             Gear^.doStep := @doStepShotIdle
             end;
 end;
@@ -4430,7 +4431,7 @@
         if (iterator^.Kind = gtDEagleShot) or (iterator^.Kind = gtSniperRifleShot) then
             begin
             // draw bullet trail
-            spawnBulletTrail(iterator);
+            spawnBulletTrail(iterator, iterator^.X, iterator^.Y);
             // the bullet can now hurt the hog that fired it
             iterator^.Data:= nil;
             end;
--- a/hedgewars/uGearsRender.pas	Sat Apr 29 23:45:14 2017 +0200
+++ b/hedgewars/uGearsRender.pas	Sat Apr 29 23:49:39 2017 +0200
@@ -820,11 +820,15 @@
                             0,
                             sign,
                             0);
-                amBaseballBat: DrawHedgehog(sx, sy,
+                amBaseballBat:
+                    begin
+                    HatVisible:= true;
+                    DrawHedgehog(sx, sy,
                             sign,
                             0,
                             5,
                             0);
+                    end
             else
                 DrawHedgehog(sx, sy,
                     sign,
@@ -1028,7 +1032,19 @@
                 amJetpack: DrawSprite(sprJetpack, sx-32, sy-32, 0);
                 end
             end; *)
-        if CurAmmoGear <> nil then
+        if (CurAmmoGear = nil) then
+            begin
+            if ((Gear^.State and (gstAttacked or gstAnimation or gstHHJumping)) = 0)
+            and (Gear^.Message and (gmLeft or gmRight) = 0) then
+            begin
+                amt:= CurrentHedgehog^.CurAmmoType;
+                case amt of
+                    amBaseballBat: DrawSpritePivotedF(sprHandBaseball,
+                        sx + 9 * sign, sy + 2, 0, sign, -8, 1, aangle);
+                end;
+            end;
+            end
+        else
             begin
             aangle:= Gear^.Angle * 180 / cMaxAngle - 90;
             case CurAmmoGear^.Kind of
--- a/hedgewars/uGearsUtils.pas	Sat Apr 29 23:45:14 2017 +0200
+++ b/hedgewars/uGearsUtils.pas	Sat Apr 29 23:49:39 2017 +0200
@@ -777,7 +777,6 @@
         PlaySound(sndWarp);
         RenderHealth(gear^.Hedgehog^);
         s:= ansistring(gear^.Hedgehog^.Name);
-        AddCaption(FormatA(GetEventString(eidResurrected), s), cWhiteColor, capgrpMessage);
         ScriptCall('onGearResurrect', gear^.uid);
         gear^.State := gstWait;
         end;
--- a/hedgewars/uScript.pas	Sat Apr 29 23:45:14 2017 +0200
+++ b/hedgewars/uScript.pas	Sat Apr 29 23:49:39 2017 +0200
@@ -1638,8 +1638,14 @@
                 end;
 
             SwitchCurrentHedgehog(gear^.Hedgehog);
+            AmmoMenuInvalidated:= true;
             CurrentTeam:= CurrentHedgehog^.Team;
 
+            repeat
+                CurrentTeam^.CurrHedgehog := (CurrentTeam^.CurrHedgehog + 1) mod CurrentTeam^.HedgehogsNumber
+            until
+                CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear = CurrentHedgehog^.Gear;
+
             gear^.State:= gear^.State or gstHHDriven;
             gear^.Active := true;
             gear^.Z := cCurrHHZ;
@@ -1937,6 +1943,27 @@
     lc_sendstat:= 0
 end;
 
+function lc_sendgameresultoff(L : Plua_State) : LongInt; Cdecl;
+begin
+    L:= L; // avoid compiler hint
+    uStats.SendGameResultOn := false;
+    lc_sendgameresultoff:= 0
+end;
+
+function lc_sendrankingstatsoff(L : Plua_State) : LongInt; Cdecl;
+begin
+    L:= L; // avoid compiler hint
+    uStats.SendRankingStatsOn := false;
+    lc_sendrankingstatsoff:= 0
+end;
+
+function lc_sendachievementsstatsoff(L : Plua_State) : LongInt; Cdecl;
+begin
+    L:= L; // avoid compiler hint
+    uStats.SendAchievementsStatsOn := false;
+    lc_sendachievementsstatsoff:= 0
+end;
+
 function lc_sendhealthstatsoff(L : Plua_State) : LongInt; Cdecl;
 begin
     L:= L; // avoid compiler hint
@@ -2520,9 +2547,15 @@
     if CheckLuaParamCount(L, 1, 'HideHog', 'gearUid') then
         begin
         gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
-        HideHog(gear^.hedgehog)
+        if (gear <> nil) and (gear^.hedgehog <> nil) then
+            begin
+            HideHog(gear^.hedgehog);
+            lua_pushboolean(L, true);
+            end
+        else
+            lua_pushboolean(L, false);
         end;
-    lc_hidehog := 0;
+    lc_hidehog := 1;
 end;
 
 function lc_restorehog(L: Plua_State): LongInt; Cdecl;
@@ -3409,6 +3442,9 @@
 lua_register(luaState, _P'EndGame', @lc_endgame);
 lua_register(luaState, _P'EndTurn', @lc_endturn);
 lua_register(luaState, _P'SendStat', @lc_sendstat);
+lua_register(luaState, _P'SendGameResultOff', @lc_sendgameresultoff);
+lua_register(luaState, _P'SendRankingStatsOff', @lc_sendrankingstatsoff);
+lua_register(luaState, _P'SendAchievementsStatsOff', @lc_sendachievementsstatsoff);
 lua_register(luaState, _P'SendHealthStatsOff', @lc_sendhealthstatsoff);
 lua_register(luaState, _P'FindPlace', @lc_findplace);
 lua_register(luaState, _P'SetGearPosition', @lc_setgearposition);
--- a/hedgewars/uStats.pas	Sat Apr 29 23:45:14 2017 +0200
+++ b/hedgewars/uStats.pas	Sat Apr 29 23:49:39 2017 +0200
@@ -24,6 +24,9 @@
 
 var TotalRounds: LongInt;
     FinishedTurnsTotal: LongInt;
+    SendGameResultOn : boolean = true;
+    SendRankingStatsOn : boolean = true;
+    SendAchievementsStatsOn : boolean = true;
     SendHealthStatsOn : boolean = true;
 
 procedure initModule;
@@ -98,6 +101,7 @@
 
 if killed then
     begin
+    Gear^.Hedgehog^.stats.StepDied:= true;
     inc(Attacker^.stats.StepKills);
     inc(Kills);
     inc(KillsTotal);
@@ -146,7 +150,7 @@
         AddVoice(sndFirstBlood, CurrentTeam^.voicepack)
 
     // Hog hurts, poisons or kills itself (except sacrifice)
-    else if (CurrentHedgehog^.stats.Sacrificed = false) and ((CurrentHedgehog^.stats.StepDamageRecv > 0) or (CurrentHedgehog^.stats.StepPoisoned) or (CurrentHedgehog^.Gear = nil)) then
+    else if (CurrentHedgehog^.stats.Sacrificed = false) and ((CurrentHedgehog^.stats.StepDamageRecv > 0) or (CurrentHedgehog^.stats.StepPoisoned) or (CurrentHedgehog^.stats.StepDied)) then
         begin
         AddVoice(sndStupid, PreviousTeam^.voicepack);
         // Message for hurting itself only (not drowning)
@@ -215,6 +219,7 @@
                 StepDamageRecv:= 0;
                 StepDamageGiven:= 0;
                 StepPoisoned:= false;
+                StepDied:= false;
                 end;
 
 if SendHealthStatsOn then
@@ -276,7 +281,7 @@
     for t:= 0 to Pred(TeamsCount) do
         with TeamsArray[t]^ do
         begin
-            if not ExtDriven then
+            if (not ExtDriven) and SendRankingStatsOn then
                 SendStat(siTeamStats, GetTeamStatString(TeamsArray[t]));
             for i:= 0 to cMaxHHIndex do
                 begin
@@ -300,8 +305,9 @@
             if Clan^.ClanHealth > 0 then
                 begin
                 winnersClan:= Clan;
-                SendStat(siPlayerKills, IntToStr(Clan^.Color) + ' ' +
-                    IntToStr(stats.Kills) + ' ' + TeamName);
+                if SendRankingStatsOn then
+                    SendStat(siPlayerKills, IntToStr(Clan^.Color) + ' ' +
+                        IntToStr(stats.Kills) + ' ' + TeamName);
             end;
 
             { determine maximum values of TeamKills, TurnSkips, TeamDamage }
@@ -324,32 +330,37 @@
         end;
 
     { now send player stats for loser teams }
-    for t:= 0 to Pred(TeamsCount) do
-        begin
-        with TeamsArray[t]^ do
+    if SendRankingStatsOn then
+        for t:= 0 to Pred(TeamsCount) do
             begin
-            if Clan^.ClanHealth = 0 then
+            with TeamsArray[t]^ do
                 begin
-                SendStat(siPlayerKills, IntToStr(Clan^.Color) + ' ' +
-                    IntToStr(stats.Kills) + ' ' + TeamName);
+                if Clan^.ClanHealth = 0 then
+                    begin
+                    SendStat(siPlayerKills, IntToStr(Clan^.Color) + ' ' +
+                        IntToStr(stats.Kills) + ' ' + TeamName);
+                end;
             end;
         end;
-    end;
 
-    if msdhh <> nil then
-        SendStat(siMaxStepDamage, IntToStr(msd) + ' ' + msdhh^.Name + ' (' + msdhh^.Team^.TeamName + ')');
-    if mskcnt = 1 then
-        SendStat(siMaxStepKills, IntToStr(msk) + ' ' + mskhh^.Name + ' (' + mskhh^.Team^.TeamName + ')');
+    // “Achievements” / Details part of stats screen
+    if SendAchievementsStatsOn then
+        begin
+        if msdhh <> nil then
+            SendStat(siMaxStepDamage, IntToStr(msd) + ' ' + msdhh^.Name + ' (' + msdhh^.Team^.TeamName + ')');
+        if mskcnt = 1 then
+            SendStat(siMaxStepKills, IntToStr(msk) + ' ' + mskhh^.Name + ' (' + mskhh^.Team^.TeamName + ')');
 
-    if maxTeamKills > 1 then
-        SendStat(siMaxTeamKills, IntToStr(maxTeamKills) + ' ' + maxTeamKillsName);
-    if maxTurnSkips > 2 then
-        SendStat(siMaxTurnSkips, IntToStr(maxTurnSkips) + ' ' + maxTurnSkipsName);
-    if maxTeamDamage > 30 then
-        SendStat(siMaxTeamDamage, IntToStr(maxTeamDamage) + ' ' + maxTeamDamageName);
+        if maxTeamKills > 1 then
+            SendStat(siMaxTeamKills, IntToStr(maxTeamKills) + ' ' + maxTeamKillsName);
+        if maxTurnSkips > 2 then
+            SendStat(siMaxTurnSkips, IntToStr(maxTurnSkips) + ' ' + maxTurnSkipsName);
+        if maxTeamDamage > 30 then
+            SendStat(siMaxTeamDamage, IntToStr(maxTeamDamage) + ' ' + maxTeamDamageName);
 
-    if KilledHHs > 0 then
-        SendStat(siKilledHHs, IntToStr(KilledHHs));
+        if KilledHHs > 0 then
+            SendStat(siKilledHHs, IntToStr(KilledHHs));
+        end;
 
     // now to console
     if winnersClan <> nil then
--- a/hedgewars/uTeams.pas	Sat Apr 29 23:45:14 2017 +0200
+++ b/hedgewars/uTeams.pas	Sat Apr 29 23:49:39 2017 +0200
@@ -82,7 +82,8 @@
     if AliveCount = 0 then
         begin // draw
         AddCaption(GetEventString(eidRoundDraw), cWhiteColor, capgrpGameState);
-        SendStat(siGameResult, shortstring(trmsg[sidDraw]));
+        if SendGameResultOn then
+            SendStat(siGameResult, shortstring(trmsg[sidDraw]));
         AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000);
         end
     else // win
@@ -113,7 +114,8 @@
                 AddVoice(sndVictory, Teams[0]^.voicepack);
 
             AddCaption(cap, cWhiteColor, capgrpGameState);
-            SendStat(siGameResult, shortstring(s));
+            if SendGameResultOn then
+                SendStat(siGameResult, shortstring(s));
             AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000)
             end;
     SendStats;
--- a/hedgewars/uTypes.pas	Sat Apr 29 23:45:14 2017 +0200
+++ b/hedgewars/uTypes.pas	Sat Apr 29 23:49:39 2017 +0200
@@ -330,6 +330,7 @@
         StepDamageGiven,
         StepKills: Longword;
         StepPoisoned,
+        StepDied,
         Sacrificed: boolean;
         MaxStepDamageRecv,
         MaxStepDamageGiven,
Binary file share/hedgewars/Data/Graphics/missions.png has changed
--- a/share/hedgewars/Data/Locale/en.txt	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Locale/en.txt	Sat Apr 29 23:49:39 2017 +0200
@@ -259,7 +259,7 @@
 02:02=Losing is not an option
 02:02=Cry havoc! Let loose the hogs of war!
 02:02=Hedgewars, brought to you by Hedgewars.org
-02:02=GL HF
+02:02=Good luck, and have fun!
 02:02=Just count yourself lucky you're not up against Tiyuri
 02:02=Just count yourself lucky you're not up against unC0Rr
 02:02=Just count yourself lucky you're not up against Nemo
@@ -618,7 +618,7 @@
 02:12=%1 feels the poison
 02:12=%1 feels weaker and weaker
 
-; Hog (%1) was resurrected. Remember that hogs can also be resurrected by the game style (e.g. AI Survival)
+; Hog (%1) was resurrected by the Resurrector utility
 02:13=%1 has been resurrected
 02:13=%1 has been brought back TO hell
 02:13=%1 gets a second chance
--- a/share/hedgewars/Data/Maps/Knockball/CMakeLists.txt	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Maps/Knockball/CMakeLists.txt	Sat Apr 29 23:49:39 2017 +0200
@@ -1,6 +1,7 @@
 install(FILES
     map.png
     map.cfg
+    map.hwp
     map.lua
     preview.png
     desc.txt
Binary file share/hedgewars/Data/Maps/Knockball/map.hwp has changed
--- a/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/backstab.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/backstab.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -70,6 +70,9 @@
 spyHog = nil
 deployedHog = nil
 deployedDead = false
+nativesTeleported = false
+nativesIsolated = false
+hogDeployed = false
 
 cyborgHidden = false
 needToAct = 0
@@ -395,28 +398,31 @@
 end
 
 function IsolateNatives()
-  PlaceGirder(710, 299, 6)
-  PlaceGirder(690, 299, 6)
-  PlaceGirder(761, 209, 4)
-  PlaceGirder(921, 209, 4)
-  PlaceGirder(1081, 209, 4)
-  PlaceGirder(761, 189, 4)
-  PlaceGirder(921, 189, 4)
-  PlaceGirder(1081, 189, 4)
-  PlaceGirder(761, 169, 4)
-  PlaceGirder(921, 169, 4)
-  PlaceGirder(1081, 169, 4)
-  PlaceGirder(761, 149, 4)
-  PlaceGirder(921, 149, 4)
-  PlaceGirder(1081, 149, 4)
-  PlaceGirder(761, 129, 4)
-  PlaceGirder(921, 129, 4)
-  PlaceGirder(1081, 129, 4)
-  PlaceGirder(1120, 261, 2)
-  PlaceGirder(1140, 261, 2)
-  PlaceGirder(1160, 261, 2)
-  AddAmmo(deployedHog, amDEagle, 0)
-  AddAmmo(deployedHog, amFirePunch, 0)
+  if not nativesIsolated then
+    PlaceGirder(710, 299, 6)
+    PlaceGirder(690, 299, 6)
+    PlaceGirder(761, 209, 4)
+    PlaceGirder(921, 209, 4)
+    PlaceGirder(1081, 209, 4)
+    PlaceGirder(761, 189, 4)
+    PlaceGirder(921, 189, 4)
+    PlaceGirder(1081, 189, 4)
+    PlaceGirder(761, 169, 4)
+    PlaceGirder(921, 169, 4)
+    PlaceGirder(1081, 169, 4)
+    PlaceGirder(761, 149, 4)
+    PlaceGirder(921, 149, 4)
+    PlaceGirder(1081, 149, 4)
+    PlaceGirder(761, 129, 4)
+    PlaceGirder(921, 129, 4)
+    PlaceGirder(1081, 129, 4)
+    PlaceGirder(1120, 261, 2)
+    PlaceGirder(1140, 261, 2)
+    PlaceGirder(1160, 261, 2)
+    AddAmmo(deployedHog, amDEagle, 0)
+    AddAmmo(deployedHog, amFirePunch, 0)
+    nativesIsolated = true
+  end
 end
 
 function PutCGI()
@@ -443,11 +449,14 @@
 end
 
 function TeleportNatives()
-  nativePos[waterNum] = {1100, 288}
-  for i = 1, 7 do
-    if nativeDead[i] ~= true then 
-      AnimTeleportGear(natives[i], unpack(nativePos[i]))
-    end
+  if not nativesTeleported then
+     nativePos[waterNum] = {1100, 288}
+     for i = 1, 7 do
+       if nativeDead[i] ~= true then 
+         AnimTeleportGear(natives[i], unpack(nativePos[i]))
+       end
+     end
+     nativesTeleported = true
   end
 end
 
@@ -464,10 +473,13 @@
 end
 
 function DeployHog()
-  AnimSwitchHog(deployedHog)
-  AnimTeleportGear(deployedHog, unpack(deployedPos))
-  if deployedHog ~= natives[wiseNum] then
-    AnimSay(deployedHog, loc("Why me?!"), SAY_THINK, 2000)
+  if not hogDeployed then
+     AnimSwitchHog(deployedHog)
+     AnimTeleportGear(deployedHog, unpack(deployedPos))
+     if deployedHog ~= natives[wiseNum] then
+        AnimSay(deployedHog, loc("Why me?!"), SAY_THINK, 2000)
+     end
+     hogDeployed = true
   end
 end
 
@@ -546,10 +558,10 @@
 
 function SkipWave2DeadAnim()
   TeleportNatives()
-  IsolateNatives()
+  PutCircles()
   DeployHog()
+  IsolateNatives()
   HideCyborg()
-  PutCircles()
 end
 
 function SpawnPlatformCrates()
@@ -569,7 +581,7 @@
   AddEvent(CheckTurnsOver, {}, DoTurnsOver, {3}, 0)
   AddEvent(CheckWaveDead, {3}, DoWaveDead, {3}, 0)
   AddEvent(CheckDeployedDead, {}, DoDeployedDead, {}, 0)
-  TurnTimeLeft = 0
+  EndTurn(true)
   ShowMission(loc("Backstab"), loc("Drills"), loc("You have 7 turns until the next wave arrives.|Make sure the arriving cannibals are greeted appropriately!|If the hog dies, the cause is lost.|Hint: you might want to use some mines..."), 1, 12000)
 end
 
@@ -598,7 +610,7 @@
 
 function AfterStartAnim()
   AnimSwitchHog(natives[leaksNum])
-  TurnTimeLeft = 0
+  EndTurn(true)
   stage = spyKillStage
   AddEvent(CheckChoice, {}, DoChoice, {}, 0)
   AddEvent(CheckKilledOther, {}, DoKilledOther, {}, 0)
@@ -620,7 +632,7 @@
   DismissTeam(loc("Natives"))
   DismissTeam(loc("Tribe"))
   DismissTeam(loc("011101001"))
-  TurnTimeLeft = 0
+  EndTurn(true)
 end
 
 function CheckChoice()
@@ -664,7 +676,7 @@
   ShowMission(loc("Backstab"), loc("Brutus"), loc("You have killed an innocent hedgehog!"), 0, 6000)
   DismissTeam(loc("Natives"))
   DismissTeam(loc("Tribe"))
-  TurnTimeLeft = 0
+  EndTurn(true)
 end
 
 function CheckWaveDead(index)
@@ -677,7 +689,7 @@
 end
 
 function DoWaveDead(index)
-  TurnTimeLeft = 0
+  EndTurn(true)
   needToAct = index
 end
 
@@ -774,7 +786,7 @@
   DismissTeam(loc("Assault Team"))
   DismissTeam(loc("Reinforcements"))
   DismissTeam(loc("011101001"))
-  TurnTimeLeft = 0
+  EndTurn(true)
 end
 
 -----------------------------Misc--------------------------------------
@@ -842,8 +854,7 @@
 
 function SetupPlace()
   startNativesNum = nativesNum
-  HideHog(cyborg)
-  cyborgHidden = true
+  HideCyborg()
   for i = 1, 9 do
     HideHog(cannibals[i])
     cannibalHidden[i] = true
@@ -1048,7 +1059,7 @@
   end
 
   if GetHogTeamName(CurrentHedgehog) == loc("Tribe") then
-    TurnTimeLeft = 0
+    EndTurn(true)
     return
   end
   TurnsLeft = TurnsLeft - 1
@@ -1059,7 +1070,7 @@
 
   if stage == spyKillStage then
     if CurrentHedgehog == spyHog or GetHogTeamName(CurrentHedgehog) ~= loc("Natives") then
-      TurnTimeLeft = 0
+      EndTurn(true)
     else
       SetGearMessage(CurrentHedgehog, 0)
       --AnimSwitchHog(natives[leaksNum])
--- a/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/enemy.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/enemy.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -286,7 +286,7 @@
   ShowMission(loc("The Enemy Of My Enemy"), loc("The Union"), loc("Defeat the cyborgs!"), 1, 0)
   PutWeaponCrates()
   PutHealthCrates()
-  TurnTimeLeft = 0
+  EndTurn(true)
 end
 
 function PutHealthCrates()
@@ -331,12 +331,12 @@
 
 function DoNativesDead()
   nativesDeadFresh = true
-  TurnTimeLeft = 0
+  EndTurn(true)
 end
 
 function DoCannibalsDead()
   cannibalsDeadFresh = true
-  TurnTimeLeft = 0
+  EndTurn(true)
 end
 
 function DoPlayersDead()
@@ -344,14 +344,14 @@
   RemoveEventFunc(CheckCannibalsDead)
   RemoveEventFunc(CheckCyborgsDead)
   playersDeadFresh = true
-  TurnTimeLeft = 0
+  EndTurn(true)
 end
 
 function DoCyborgsDead()
 --  RemoveEventFunc(CheckNativesDead)
 --  RemoveEventFunc(CheckCannibalsDead)
   cyborgsDeadFresh= true
-  TurnTimeLeft = 0
+  EndTurn(true)
 end
 
 function CheckGearsDead(gearList)
@@ -388,7 +388,7 @@
   DismissTeam(loc("Natives"))
   DismissTeam(loc("Cannibals"))
   DismissTeam(loc("011101001"))
-  TurnTimeLeft = 0
+  EndTurn(true)
 end
 
 function WonMission()
@@ -404,7 +404,7 @@
     SaveCampaignVar("Progress", "9")
   end
   DismissTeam(loc("011101001"))
-  TurnTimeLeft = 0
+  EndTurn(true)
 end
 -----------------------------Misc--------------------------------------
 function HideHedge(hedge)
--- a/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/epil.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/epil.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -71,6 +71,7 @@
 startAnim = {}
 
 gearDead = {}
+hogDead = {}
 --------------------------Anim skip functions--------------------------
 function SkipStartAnim()
   SetGearMessage(CurrentHedgehog, 0)
@@ -81,7 +82,7 @@
   crate = SpawnHealthCrate(0, 0)
   SetGearMessage(CurrentHedgehog, 0)
   AddNewEvent(CheckCrateTaken, {}, DoCrateTaken, {}, 1)
-  TurnTimeLeft = 0
+  EndTurn(true)
   ShowMission(loc("Epilogue"), loc("That's all, folks!"),
     loc("You have successfully finished the campaign!").."|"..
     loc("If you wish to replay, there are other possible endings, too!").."|"..
@@ -380,8 +381,17 @@
   CheckEvents()
 end
 
+function onGearAdd(gear)
+  if GetGearType(gear) == gtHedgehog then
+    hogDead[gear] = false
+  end
+end
+
 function onGearDelete(gear)
   gearDead[gear] = true
+  if GetGearType(gear) == gtHedgehog then
+    hogDead[gear] = true
+  end
 end
 
 function onAmmoStoreInit()
@@ -421,13 +431,23 @@
   SetAmmo(amWhip, 9, 0, 0, 0)
 end
 
+function IsEveryoneExceptTraitorDead()
+  for id, isDead in pairs(hogDead) do
+    if id ~= traitor and not isDead then
+      return false
+    end
+  end
+  return true
+end
+
 function onNewTurn()
   if AnimInProgress() then
     TurnTimeLeft = -1
     return
   end
-  if CurrentHedgehog == traitor then
-    TurnTimeLeft = 0
+  -- Don't allow player to play with traitor, except when it is the final hog left
+  if CurrentHedgehog == traitor and not IsEveryoneExceptTraitorDead() then
+    EndTurn(true)
   else
     TurnTimeLeft = -1
   end
--- a/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/family.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/family.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -100,6 +100,8 @@
 freshDead = nil
 crates = {}
 cratesNum = 0
+
+princessFreed = false
 -----------------------------Animations--------------------------------
 function EmitDenseClouds(dir)
   local dif
@@ -185,7 +187,7 @@
   SetupPlace3()
   SetGearMessage(natives[1], 0)
   AddNewEvent(CheckPrincessFreed, {}, DoPrincessFreed, {}, 0)
-  TurnTimeLeft = 0
+  EndTurn(true)
   ShowMission(loc("Family Reunion"), loc("Salvation"), loc("Get your teammates out of their natural prison and save the princess!|Hint: Drilling holes should solve everything.|Hint: It might be a good idea to place a girder before starting to drill. Just saying.|Hint: All your hedgehogs need to be above the marked height!|Hint: Leaks A Lot needs to get really close to the princess!"), 1, 7000)
   vCirc = AddVisualGear(0,0,vgtCircle,0,true)
   SetVisualGearValues(vCirc, 2625, 1500, 100, 255, 1, 10, 0, 120, 3, 0xff00ffff)
@@ -287,8 +289,9 @@
   if progress and progress<7 then
     SaveCampaignVar("Progress", "7")
   end
+  princessFreed = true
   DismissTeam(loc("011101001"))
-  TurnTimeLeft = 0
+  EndTurn(true)
 end
 
 function CheckCyborgsDead()
@@ -337,11 +340,13 @@
 end
 
 function EndMission()
-  RemoveEventFunc(CheckPrincessFreed)
-  AddCaption(loc("So the princess was never heard of again ..."))
-  DismissTeam(loc("Natives"))
-  DismissTeam(loc("011101001"))
-  TurnTimeLeft = 0
+  if not princessFreed then
+    RemoveEventFunc(CheckPrincessFreed)
+    AddCaption(loc("So the princess was never heard of again ..."))
+    DismissTeam(loc("Natives"))
+    DismissTeam(loc("011101001"))
+    EndTurn(true)
+  end
 end
 
 function CheckOutOfCluster()
@@ -546,7 +551,7 @@
         end
       end
     end
-    TurnTimeLeft = 0
+    EndTurn(true)
   else
     for i = 1, 3 do
       if gearDead[natives[i]] ~= true then
--- a/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/journey.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/journey.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -32,8 +32,6 @@
 TurnsLeft = 0
 stage = 0
 
---cyborgHidden = false
---princessHidden = false
 blowTaken = false
 fireTaken = false
 gravityTaken = false
@@ -45,6 +43,7 @@
 denseDead = false
 princessDead = false
 cyborgDead = false
+victory = false
 cannibalDead = {}
 hedgeHidden = {}
 
@@ -73,7 +72,6 @@
 endAnimRL = {}
 
 endFailAnim = {}
-endFailAnimAD = {}
 
 winAnim = {}
 winAnimAD = {}
@@ -81,7 +79,7 @@
 --/////////////////////////Animation Functions///////////////////////
 function AfterMidFailAnim()
   DismissTeam(loc("Natives"))
-  TurnTimeLeft = 0
+  EndTurn(true)
 end
 
 function AfterMidAnimAlone()
@@ -100,9 +98,10 @@
   SetGearMessage(leaks, 0)
   TurnsLeft = 12
   TurnTimeLeft = TurnTime
-  ShowMission(loc("The Journey Back"), loc("Collateral Damage"), loc("Save the princess by collecting the crate in under 12 turns!"), 0, 6000)
+  ShowMission(loc("The Journey Back"), loc("Collateral Damage"),
+    loc("Save the princess by collecting the crate in under 12 turns!") .. "|" ..
+    loc("Mines time: 3 seconds"), 0, 6000)
   -----------------------///////////////------------
-  --AnimSetGearPosition(leaks, 417, 1800)
 end
 
 function SkipEndAnimAlone()
@@ -185,33 +184,33 @@
 end
 
 function PlaceMinesDuo()
-  SetTimer(AddGear(2920, 1448, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2985, 1338, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(3005, 1302, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(3030, 1270, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(3046, 1257, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2954, 1400, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2967, 1385, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2849, 1449, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2811, 1436, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2773, 1411, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2732, 1390, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2700, 1362, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2642, 1321, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2172, 1417, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2190, 1363, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2219, 1332, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1201, 1207, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1247, 1205, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1295, 1212, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1356, 1209, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1416, 1201, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1466, 1201, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1678, 1198, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1738, 1198, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1796, 1198, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1637, 1217, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1519, 1213, gtMine, 0, 0, 0, 0), 5000)
+  AddGear(2920, 1448, gtMine, 0, 0, 0, 0)
+  AddGear(2985, 1338, gtMine, 0, 0, 0, 0)
+  AddGear(3005, 1302, gtMine, 0, 0, 0, 0)
+  AddGear(3030, 1270, gtMine, 0, 0, 0, 0)
+  AddGear(3046, 1257, gtMine, 0, 0, 0, 0)
+  AddGear(2954, 1400, gtMine, 0, 0, 0, 0)
+  AddGear(2967, 1385, gtMine, 0, 0, 0, 0)
+  AddGear(2849, 1449, gtMine, 0, 0, 0, 0)
+  AddGear(2811, 1436, gtMine, 0, 0, 0, 0)
+  AddGear(2773, 1411, gtMine, 0, 0, 0, 0)
+  AddGear(2732, 1390, gtMine, 0, 0, 0, 0)
+  AddGear(2700, 1362, gtMine, 0, 0, 0, 0)
+  AddGear(2642, 1321, gtMine, 0, 0, 0, 0)
+  AddGear(2172, 1417, gtMine, 0, 0, 0, 0)
+  AddGear(2190, 1363, gtMine, 0, 0, 0, 0)
+  AddGear(2219, 1332, gtMine, 0, 0, 0, 0)
+  AddGear(1201, 1207, gtMine, 0, 0, 0, 0)
+  AddGear(1247, 1205, gtMine, 0, 0, 0, 0)
+  AddGear(1295, 1212, gtMine, 0, 0, 0, 0)
+  AddGear(1356, 1209, gtMine, 0, 0, 0, 0)
+  AddGear(1416, 1201, gtMine, 0, 0, 0, 0)
+  AddGear(1466, 1201, gtMine, 0, 0, 0, 0)
+  AddGear(1678, 1198, gtMine, 0, 0, 0, 0)
+  AddGear(1738, 1198, gtMine, 0, 0, 0, 0)
+  AddGear(1796, 1198, gtMine, 0, 0, 0, 0)
+  AddGear(1637, 1217, gtMine, 0, 0, 0, 0)
+  AddGear(1519, 1213, gtMine, 0, 0, 0, 0)
 end
 
 function AfterPastFlowerAnim()
@@ -221,8 +220,11 @@
   AddEvent(CheckTookGirder2, {}, DoTookGirder2, {}, 0)
   SetGearMessage(leaks, 0)
   SetGearMessage(dense, 0)
-  TurnTimeLeft = 0
-  ShowMission(loc("The Journey Back"), loc("The Savior"), loc("Get Dense Cloud out of the pit!"), 1, 5000)
+  EndTurn(0)
+  ShowMission(loc("The Journey Back"), loc("The Savior"), 
+    loc("Get Dense Cloud out of the pit!") .. "|" ..
+    loc("Your hogs must survive!") .. "|" ..
+    loc("Beware of mines: They explode after 5 seconds."), 1, 5000)
 end
 
 function SkipPastFlowerAnim()
@@ -240,8 +242,12 @@
   AddEvent(CheckTookFire, {}, DoTookFire, {}, 0)
   SetGearMessage(leaks, 0)
   SetGearMessage(dense, 0)
-  TurnTimeLeft = 0
-  ShowMission(loc("The Journey Back"), loc("They never learn"), loc("Free Dense Cloud and continue the mission!"), 1, 5000)
+  EndTurn(true)
+  ShowMission(loc("The Journey Back"), loc("They never learn"),
+    loc("Free Dense Cloud and continue the mission!") .. "|" ..
+    loc("Collect the weapon crate at the left coast!") .. "|" ..
+    loc("Your hogs must survive!") .. "|" ..
+    loc("Mines time: 5 seconds"), 1, 5000)
 end
 
 function SkipOutPitAnim()
@@ -313,40 +319,40 @@
 end
 
 function DumpMines()
-  SetTimer(AddGear(2261, 1835, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2280, 1831, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2272, 1809, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2290, 1815, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2278, 1815, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2307, 1811, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2286, 1820, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2309, 1813, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2303, 1822, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2317, 1827, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2312, 1816, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2316, 1812, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2307, 1802, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2276, 1818, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2284, 1816, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2292, 1811, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2295, 1814, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2306, 1811, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2292, 1815, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2314, 1815, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2286, 1813, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2275, 1813, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2269, 1814, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2273, 1812, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2300, 1808, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2322, 1812, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2323, 1813, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2311, 1811, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2303, 1809, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2287, 1808, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2282, 1808, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2277, 1809, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2296, 1809, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(2314, 1818, gtMine, 0, 0, 0, 0), 5000)
+  AddGear(2261, 1835, gtMine, 0, 0, 0, 0)
+  AddGear(2280, 1831, gtMine, 0, 0, 0, 0)
+  AddGear(2272, 1809, gtMine, 0, 0, 0, 0)
+  AddGear(2290, 1815, gtMine, 0, 0, 0, 0)
+  AddGear(2278, 1815, gtMine, 0, 0, 0, 0)
+  AddGear(2307, 1811, gtMine, 0, 0, 0, 0)
+  AddGear(2286, 1820, gtMine, 0, 0, 0, 0)
+  AddGear(2309, 1813, gtMine, 0, 0, 0, 0)
+  AddGear(2303, 1822, gtMine, 0, 0, 0, 0)
+  AddGear(2317, 1827, gtMine, 0, 0, 0, 0)
+  AddGear(2312, 1816, gtMine, 0, 0, 0, 0)
+  AddGear(2316, 1812, gtMine, 0, 0, 0, 0)
+  AddGear(2307, 1802, gtMine, 0, 0, 0, 0)
+  AddGear(2276, 1818, gtMine, 0, 0, 0, 0)
+  AddGear(2284, 1816, gtMine, 0, 0, 0, 0)
+  AddGear(2292, 1811, gtMine, 0, 0, 0, 0)
+  AddGear(2295, 1814, gtMine, 0, 0, 0, 0)
+  AddGear(2306, 1811, gtMine, 0, 0, 0, 0)
+  AddGear(2292, 1815, gtMine, 0, 0, 0, 0)
+  AddGear(2314, 1815, gtMine, 0, 0, 0, 0)
+  AddGear(2286, 1813, gtMine, 0, 0, 0, 0)
+  AddGear(2275, 1813, gtMine, 0, 0, 0, 0)
+  AddGear(2269, 1814, gtMine, 0, 0, 0, 0)
+  AddGear(2273, 1812, gtMine, 0, 0, 0, 0)
+  AddGear(2300, 1808, gtMine, 0, 0, 0, 0)
+  AddGear(2322, 1812, gtMine, 0, 0, 0, 0)
+  AddGear(2323, 1813, gtMine, 0, 0, 0, 0)
+  AddGear(2311, 1811, gtMine, 0, 0, 0, 0)
+  AddGear(2303, 1809, gtMine, 0, 0, 0, 0)
+  AddGear(2287, 1808, gtMine, 0, 0, 0, 0)
+  AddGear(2282, 1808, gtMine, 0, 0, 0, 0)
+  AddGear(2277, 1809, gtMine, 0, 0, 0, 0)
+  AddGear(2296, 1809, gtMine, 0, 0, 0, 0)
+  AddGear(2314, 1818, gtMine, 0, 0, 0, 0)
 end
 
 function SetupAnimRefusedDied()
@@ -439,7 +445,6 @@
   midAnim = midAnimAD
   failAnim = failAnimAD
   endAnim = endAnimAD
-  endFailAnim = endFailAnimAD
   winAnim = winAnimAD
 end
 
@@ -569,7 +574,7 @@
 
 function KillPrincess()
   DismissTeam(loc("Cannibal Sentry"))
-  TurnTimeLeft = 0
+  EndTurn(true)
 end
 --/////////////////////////////Misc Functions////////////////////////
 
@@ -600,7 +605,6 @@
 
 function SetupPlaceAlone()
   ------ AMMO CRATE LIST ------
-  --SpawnAmmoCrate(3122, 994, amShotgun)
   SpawnAmmoCrate(3124, 952, amBaseballBat)
   SpawnAmmoCrate(2508, 1110, amFirePunch)
   ------ UTILITY CRATE LIST ------
@@ -610,23 +614,22 @@
   SpawnUtilityCrate(3113, 911, amParachute)
   sniperCrate = SpawnAmmoCrate(784, 1715, amSniperRifle)
   ------ MINE LIST ------
-  SetTimer(AddGear(3328, 1399, gtMine, 0, 0, 0, 0), 3000)
-  SetTimer(AddGear(3028, 1262, gtMine, 0, 0, 0, 0), 3000)
-  SetTimer(AddGear(2994, 1274, gtMine, 0, 0, 0, 0), 3000)
-  SetTimer(AddGear(2956, 1277, gtMine, 0, 0, 0, 0), 3000)
-  SetTimer(AddGear(2925, 1282, gtMine, 0, 0, 0, 0), 3000)
-  SetTimer(AddGear(2838, 1276, gtMine, 0, 0, 0, 0), 3000)
-  SetTimer(AddGear(2822, 1278, gtMine, 0, 0, 0, 0), 3000)
-  SetTimer(AddGear(2786, 1283, gtMine, 0, 0, 0, 0), 3000)
-  SetTimer(AddGear(2766, 1270, gtMine, 0, 0, 0, 0), 3000)
-  SetTimer(AddGear(2749, 1231, gtMine, 0, 0, 0, 0), 3000)
-  SetTimer(AddGear(2717, 1354, gtMine, 0, 0, 0, 0), 3000)
-  SetTimer(AddGear(2167, 1330, gtMine, 0, 0, 0, 0), 3000)
-  SetTimer(AddGear(2201, 1321, gtMine, 0, 0, 0, 0), 3000)
-  SetTimer(AddGear(2239, 1295, gtMine, 0, 0, 0, 0), 3000)
+  AddGear(3328, 1399, gtMine, 0, 0, 0, 0)
+  AddGear(3028, 1262, gtMine, 0, 0, 0, 0)
+  AddGear(2994, 1274, gtMine, 0, 0, 0, 0)
+  AddGear(2956, 1277, gtMine, 0, 0, 0, 0)
+  AddGear(2925, 1282, gtMine, 0, 0, 0, 0)
+  AddGear(2838, 1276, gtMine, 0, 0, 0, 0)
+  AddGear(2822, 1278, gtMine, 0, 0, 0, 0)
+  AddGear(2786, 1283, gtMine, 0, 0, 0, 0)
+  AddGear(2766, 1270, gtMine, 0, 0, 0, 0)
+  AddGear(2749, 1231, gtMine, 0, 0, 0, 0)
+  AddGear(2717, 1354, gtMine, 0, 0, 0, 0)
+  AddGear(2167, 1330, gtMine, 0, 0, 0, 0)
+  AddGear(2201, 1321, gtMine, 0, 0, 0, 0)
+  AddGear(2239, 1295, gtMine, 0, 0, 0, 0)
 
   AnimSetGearPosition(leaks, 3781, 1583)
-  --AnimSetGearPosition(leaks, 1650, 1583)
   AddAmmo(cannibals[1], amShotgun, 100)
   AddAmmo(leaks, amSwitch, 0)
 end
@@ -730,17 +733,17 @@
 end
 
 function PlaceCourseMines()
-  SetTimer(AddGear(1215, 1193, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1259, 1199, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1310, 1198, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1346, 1196, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1383, 1192, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1436, 1196, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1487, 1199, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1651, 1209, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1708, 1209, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1759, 1190, gtMine, 0, 0, 0, 0), 5000)
-  SetTimer(AddGear(1815, 1184, gtMine, 0, 0, 0, 0), 5000)
+  AddGear(1215, 1193, gtMine, 0, 0, 0, 0)
+  AddGear(1259, 1199, gtMine, 0, 0, 0, 0)
+  AddGear(1310, 1198, gtMine, 0, 0, 0, 0)
+  AddGear(1346, 1196, gtMine, 0, 0, 0, 0)
+  AddGear(1383, 1192, gtMine, 0, 0, 0, 0)
+  AddGear(1436, 1196, gtMine, 0, 0, 0, 0)
+  AddGear(1487, 1199, gtMine, 0, 0, 0, 0)
+  AddGear(1651, 1209, gtMine, 0, 0, 0, 0)
+  AddGear(1708, 1209, gtMine, 0, 0, 0, 0)
+  AddGear(1759, 1190, gtMine, 0, 0, 0, 0)
+  AddGear(1815, 1184, gtMine, 0, 0, 0, 0)
 end
 
 
@@ -770,11 +773,15 @@
 end
 
 function CheckDensePit()
-  return GetY(dense) < 1250 and StoppedGear(dense)
+  if GetHealth(dense) ~= nil then
+    return GetY(dense) < 1250 and StoppedGear(dense)
+  else
+    return false
+  end
 end
 
 function DoDensePit()
-  TurnTimeLeft = 0
+  EndTurn(0)
   RestoreHedge(cyborg)
   AnimWait(cyborg, 1)
   AddFunction({func = AddAnim, args = {outPitAnim}})
@@ -790,7 +797,7 @@
 end
 
 function DoPastFlower()
-  TurnTimeLeft = 0
+  EndTurn(true)
   RestoreHedge(cyborg)
   AnimWait(cyborg, 1)
   AddFunction({func = AddAnim, args = {pastFlowerAnim}})
@@ -803,8 +810,11 @@
 end
 
 function DoLeaksDead()
-  AddCaption(loc("The village, unprepared, was destroyed by the cyborgs..."))
-  DismissTeam(loc("Natives"))
+  if not princessDead then
+    EndTurn(true)
+    AddCaption(loc("The village, unprepared, was destroyed by the cyborgs..."))
+    DismissTeam(loc("Natives"))
+  end
 end
 
 function CheckDenseDead()
@@ -812,8 +822,11 @@
 end
 
 function DoDenseDead()
-  AddCaption(loc("The village, unprepared, was destroyed by the cyborgs..."))
-  DismissTeam(loc("Natives"))
+  if not princessDead then
+    EndTurn(true)
+    AddCaption(loc("The village, unprepared, was destroyed by the cyborgs..."))
+    DismissTeam(loc("Natives"))
+  end
 end
 
 function CheckTookBlowTorch()
@@ -821,7 +834,10 @@
 end
 
 function DoTookBlowTorch()
-  ShowMission(loc("The Journey Back"), loc("The Tunnel Maker"), loc("Hint: Select the blowtorch, aim and press [Fire]. Press [Fire] again to stop.").."|"..loc("Don't blow up the crate."), 0, 6000)
+  ShowMission(loc("The Journey Back"), loc("The Tunnel Maker"), 
+    loc("Get past the flower.").."|"..
+    loc("Hint: Select the blow torch, aim and press [Fire]. Press [Fire] again to stop.").."|"..
+    loc("Don't blow up the crate."), 0, 6000)
 end
 
 function CheckTookLowGravity()
@@ -829,7 +845,10 @@
 end
 
 function DoTookLowGravity()
-  ShowMission(loc("The Journey Back"), loc("The Moonwalk"), loc("Hint: Select the low gravity and press [Fire]."), 0, 6000)
+  ShowMission(loc("The Journey Back"), loc("The Moonwalk"),
+    loc("Hop on top of the next flower and advance to the left coast.").."|"..
+    loc("Hint: Select the low gravity and press [Fire].") .. "|" ..
+    loc("Beware of mines: They explode after 3 seconds."), 0, 6000)
 end
 
 function CheckOnBridge()
@@ -837,7 +856,7 @@
 end
 
 function DoOnBridge()
-  TurnTimeLeft = 0
+  EndTurn(true)
   RestoreHedge(cyborg)
   RestoreHedge(princess)
   AnimWait(cyborg, 1)
@@ -860,7 +879,9 @@
 
 function DoOnFirstGirder()
   PlaceCourseMines()
-  ShowMission(loc("The Journey Back"), loc("Slippery"), loc("You'd better watch your steps..."), 0, 4000)
+  ShowMission(loc("The Journey Back"), loc("Slippery"), 
+    loc("Collect the weapon crate at the left coast!") .. "|" ..
+    loc("You'd better watch your steps..."), 0, 4000)
 end
 
 function CheckTookSniper()
@@ -868,7 +889,7 @@
 end
 
 function DoTookSniper()
-  TurnTimeLeft = 0
+  EndTurn(true)
   RestoreHedge(cyborg)
   RestoreHedge(princess)
   AnimWait(cyborg, 1)
@@ -881,7 +902,7 @@
 end
 
 function DoTookSniper2()
-  TurnTimeLeft = 0
+  EndTurn(true)
   RestoreHedge(cyborg)
   RestoreHedge(princess)
   AnimWait(cyborg, 1)
@@ -894,8 +915,12 @@
 end
 
 function DoLost()
+  if not cyborgDead then
+    SwitchHog(cyborg)
+  end
   AddAnim(endFailAnim)
-  AddFunction({func = DismissTeam, args = {loc('Natives')}})
+  AddFunction({func = DismissTeam, args = {loc("Natives")}})
+  AddFunction({func = EndTurn, args = {true}})
 end
 
 function CheckWon()
@@ -903,6 +928,7 @@
 end
 
 function DoWon()
+  victory = true
   if progress and progress<3 then
     SaveCampaignVar("Progress", "3")
   end
@@ -914,7 +940,7 @@
   SwitchHog(leaks)
   DismissTeam(loc("Cannibal Sentry"))
   DismissTeam(loc("011101001"))
-  TurnTimeLeft = 0
+  EndTurn(true)
 end
 
 function CheckFailedCourse()
@@ -922,7 +948,7 @@
 end
 
 function DoFailedCourse()
-  TurnTimeLeft = 0
+  EndTurn(true)
   RestoreHedge(cyborg)
   RestoreHedge(princess)
   AnimWait(cyborg, 1)
@@ -933,12 +959,23 @@
 --////////////////////////////Main Functions/////////////////////////
 
 function onGameInit()
+  progress = tonumber(GetCampaignVar("Progress"))
+  m2Choice = tonumber(GetCampaignVar("M2Choice"))
+  m2DenseDead = tonumber(GetCampaignVar("M2DenseDead"))
+  m2RamonDead = tonumber(GetCampaignVar("M2RamonDead"))
+  m2SpikyDead = tonumber(GetCampaignVar("M2SpikyDead"))
+
 	Seed = 0
 	GameFlags = gfSolidLand + gfDisableWind
 	TurnTime = 40000 
 	CaseFreq = 0
 	MinesNum = 0
-	MinesTime = 3000
+
+	if m2DenseDead == 1 then
+		MinesTime = 3000
+	else
+		MinesTime = 5000
+	end
 	Explosives = 0
 	Delay = 5
     Map = "A_Classic_Fairytale_journey"
@@ -977,11 +1014,6 @@
 end
 
 function onGameStart()
-  progress = tonumber(GetCampaignVar("Progress"))
-  m2Choice = tonumber(GetCampaignVar("M2Choice"))
-  m2DenseDead = tonumber(GetCampaignVar("M2DenseDead"))
-  m2RamonDead = tonumber(GetCampaignVar("M2RamonDead"))
-  m2SpikyDead = tonumber(GetCampaignVar("M2SpikyDead"))
   StartMission()
 end
 
@@ -1001,13 +1033,13 @@
     fireTaken = true
   elseif gear == gravityCrate then
     gravityTaken = true
-  elseif gear == leaks then
+  elseif gear == leaks and not victory then
     leaksDead = true
-  elseif gear == dense then
+  elseif gear == dense and not victory then
     denseDead = true
   elseif gear == cyborg then
     cyborgDead = true
-  elseif gear == princess then
+  elseif gear == princess and not victory then
     princessDead = true
   elseif gear == girderCrate then
     girderTaken = true
@@ -1045,13 +1077,15 @@
 function onNewTurn()
   if AnimInProgress() then
     TurnTimeLeft = -1
+  elseif victory then
+    EndTurn(true)
   elseif stage == endStage and CurrentHedgehog ~= leaks then
     AnimSwitchHog(leaks)
     SetGearMessage(leaks, 0)
     TurnTimeLeft = -1
   elseif GetHogTeamName(CurrentHedgehog) ~= loc("Natives") then
     for i = 1, 4 do
-      if cannibalDead[i] ~= true then
+      if cannibalDead[i] ~= true and leaksDead ~= true then
         if GetX(cannibals[i]) < GetX(leaks) then
           HogTurnLeft(cannibals[i], false)
         else
@@ -1072,8 +1106,5 @@
     SetAnimSkip(true)
     return
   end
---  AddAmmo(leaks, amRope, 100)
---  RemoveEventFunc(CheckPastFlower)
---  DeleteGear(sniperCrate)
 end
 
--- a/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/queen.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/queen.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -488,7 +488,7 @@
   SetHealth(SpawnHealthCrate(2087, 50), 25)
   SetHealth(SpawnHealthCrate(2143, 54), 25)
   SetHealth(SpawnHealthCrate(70, 1308), 25)
-  ShowMission(loc("Long Live The Queen"), loc("Bullseye"), lob("Good job! Defeat the rest of the aliens!"), 1, 0)
+  ShowMission(loc("Long Live The Queen"), loc("Bullseye"), loc("Good job! Defeat the rest of the aliens!"), 1, 0)
   TurnTimeLeft = 0
 end
 -----------------------------Events------------------------------------
--- a/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/united.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Campaign/A_Classic_Fairytale/united.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -490,7 +490,7 @@
   SetAmmo(amGirder, 4, 0, 0, 2)
   SetAmmo(amParachute, 4, 0, 0, 2)
   SetAmmo(amSwitch, 8, 0, 0, 2)
-  SetAmmo(amSkip, 8, 0, 0, 0)
+  SetAmmo(amSkip, 9, 0, 0, 0)
   SetAmmo(amRope, 5, 0, 0, 3)
   SetAmmo(amBlowTorch, 3, 0, 0, 3)
   SetAmmo(amPickHammer, 0, 0, 0, 3)
--- a/share/hedgewars/Data/Missions/Challenge/Basic_Training_-_Sniper_Rifle.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Challenge/Basic_Training_-_Sniper_Rifle.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -361,6 +361,6 @@
 		SendStat(siCustomAchievement, string.format(loc("You have made %d shots."), shots))
 		end_score_overall = end_score_targets
 	end
+	SendStat(siPointType, loc("points"))
 	SendStat(siPlayerKills, tostring(end_score_overall), loc("Sniperz"))
-	SendStat(siPointType, loc("points"))
 end
--- a/share/hedgewars/Data/Missions/Challenge/User_Mission_-_RCPlane_Challenge.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Challenge/User_Mission_-_RCPlane_Challenge.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -466,7 +466,7 @@
 			end
 			if(planesUsed == 1) then
 				SendStat(siCustomAchievement, loc("Congratulations! You have truly mastered this challenge! Don't forget to save the demo."))
-				SendStat(siCustomAchievement, string.format(loc("You have gained an achievement: %s"), loc("Prestigious Pilot")))
+				SendStat(siCustomAchievement, string.format(loc("Achievement gotten: %s"), loc("Prestigious Pilot")))
 			end
 
 			ShowMission     (
--- a/share/hedgewars/Data/Missions/Challenge/User_Mission_-_That_Sinking_Feeling.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Challenge/User_Mission_-_That_Sinking_Feeling.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -226,8 +226,8 @@
 				GameOver = true
 				AddCaption(loc("The flood has stopped! Challenge over."))
 				SendStat(siGameResult, loc("Challenge completed!"))
+				SendStat(siPointType, loc("rescues"))
 				SendStat(siPlayerKills, tostring(hhCount), loc("Nameless Heroes"))
-				SendStat(siPointType, loc("rescues"))
 
 				-- Do not count drowning hedgehogs
 				local hhLeft = hhCount
@@ -241,7 +241,7 @@
 				SendStat(siCustomAchievement, string.format(loc("You saved %d of 8 Hapless Hogs."), hhLeft))
 
 				if hhLeft == 8 then
-					AddCaption(loc("Achievement obtained: Lively Lifeguard"),0xffba00ff,capgrpMessage2)
+					AddCaption(string.format(loc("Achievement gotten: %s"), loc("Lively Lifeguard")) ,0xffba00ff,capgrpMessage2)
 					SendStat(siCustomAchievement, loc("You have obtained an achievement: Lively Lifeguard"))
 				end
 				EndGame()
@@ -290,8 +290,8 @@
 		else
 			SendStat(siCustomAchievement, loc("You haven't rescued anyone."))
 		end
+		SendStat(siPointType, loc("points"))
 		SendStat(siPlayerKills, "0", loc("Nameless Heroes"))
-		SendStat(siPointType, loc("points"))
 
 		SendStat(siGameResult, loc("Disqualified!"))
 		GameOver = true
--- a/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Bamboo_Thicket.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Bamboo_Thicket.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -25,7 +25,7 @@
 	AddTeam(loc("Pathetic Resistance"), 14483456, "Simple", "Island", "Default", "cm_yinyang")
 	player = AddHog(loc("Ikeda"), 0, 10, "StrawHat")
 			
-	AddTeam(loc("Cybernetic Empire"), 	1175851, "Simple", "Island", "Default", "cm_cyborg")
+	AddTeam(loc("Cybernetic Empire"), 	1175851, "Simple", "Island", "Robot", "cm_cyborg")
 	enemy = AddHog(loc("Unit 835"), 1, 10, "cyborg1")
 
 	SetGearPosition(player,142,656)
@@ -80,7 +80,7 @@
 		ShowMission(loc("Bamboo Thicket"), loc("MISSION SUCCESSFUL"), loc("Congratulations!"), 0, 0)
 		
 		if (turnNumber < 6) and (firedShell == false) then
-			AddCaption(loc("Achievement Unlocked") .. ": " .. loc("Energetic Engineer"),0xffba00ff,capgrpMessage2)
+			AddCaption(string.format(loc("Achievement gotten: %s"), loc("Energetic Engineer")),0xffba00ff,capgrpMessage2)
 		end
 
 	elseif gear == player then
--- a/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Dangerous_Ducklings.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Dangerous_Ducklings.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -136,7 +136,7 @@
 		elseif (gear == instructor) and (GetY(gear) > WaterLine) then
 			HogSay(player, loc("See ya!"), SAY_THINK)
 			TurnTimeLeft = 3000
-			AddCaption(loc("Achievement Unlocked") .. ": " .. loc("Naughty Ninja"),0xffba00ff,capgrpMessage2)
+			AddCaption(string.format(loc("Achievement gotten: %s"), loc("Naughty Ninja")) ,0xffba00ff,capgrpMessage2)
 			DismissTeam(loc("Blue Team"))
 			gameWon = true
 		elseif gear == enemy then
--- a/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Diver.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Diver.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -47,7 +47,10 @@
 
 	AddGear(579, 296, gtMine, 0, 0, 0, 0)
 
-	ShowMission(loc("Operation Diver"), loc("Scenario"), loc("Eliminate the enemy before the time runs out.") .. "|" .. loc("Mines time: 1 second"), -amFirePunch, 0);
+	ShowMission(loc("Diver"), loc("Scenario"),
+		loc("Eliminate the enemy before the time runs out.") .. "|" .. 
+		loc("Unlimited Attacks: Attacks don't end your turn") .. "|" ..
+		loc("Mines time: 1 second"), -amFirePunch, 0);
 	--SetTag(AddGear(0, 0, gtATSmoothWindCh, 0, 0, 0, 1), -70)
 
 	SetWind(-100)
@@ -91,9 +94,9 @@
 function onGearDelete(gear)
 
 	if (gear == enemy) and (GameOver == false) then
-		ShowMission(loc("Operation Diver"), loc("MISSION SUCCESSFUL"), loc("Congratulations!"), 0, 0)
+		ShowMission(loc("Diver"), loc("MISSION SUCCESSFUL"), loc("Congratulations!"), 0, 0)
 	elseif gear == player then
-		ShowMission(loc("Operation Diver"), loc("MISSION FAILED"), loc("Oh no! Just try again!"), -amSkip, 0)		
+		ShowMission(loc("Diver"), loc("MISSION FAILED"), loc("Oh no! Just try again!"), -amSkip, 0)		
 		GameOver = true
 	end
 
--- a/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Newton_and_the_Hammock.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Newton_and_the_Hammock.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -26,7 +26,7 @@
 	AddTeam(loc("Pathetic Resistance"), 14483456, "Simple", "Island", "Default", "cm_duckhead")
 	player = AddHog(loc("Ikeda"), 0, 48, "StrawHat")
 			
-	AddTeam(loc("Cybernetic Empire"), 	1175851, "Simple", "Island", "Default", "cm_cyborg")
+	AddTeam(loc("Cybernetic Empire"), 	1175851, "Simple", "Island", "Robot", "cm_cyborg")
 	enemy = AddHog(loc("Unit") .. " 811", 1, 100, "cyborg1")
 
 	SetGearPosition(player,430,1540)
--- a/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Nobody_Laugh.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Nobody_Laugh.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -54,7 +54,9 @@
 
 	ShowMission(	loc("Nobody Laugh"),
 					loc("Scenario"),
-					loc("Eliminate the enemy.")
+					loc("Eliminate the enemy.") .. "|" ..
+					loc("Unlimited Attacks: Attacks don't end your turn") .. "|"..
+					loc("Per-hog Ammo: Weapons are not shared between hogs")
 					, 0, 0
 				)
 
--- a/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Spooky_Tree.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Spooky_Tree.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -82,7 +82,10 @@
 	GirderCrate = SpawnAmmoCrate(1789,514,amShotgun) -- final shotgun
 	SpawnAmmoCrate(1181,419,amBee)
 
-	ShowMission(loc("Spooky Tree"), loc("Scenario"), loc("Eliminate the enemy before the time runs out.") .. "|" .. loc("Mines time: 0 seconds"), -amBee, 0)
+	ShowMission(loc("Spooky Tree"), loc("Scenario"),
+		loc("Eliminate the enemy before the time runs out.") .. "|" ..
+		loc("Unlimited Attacks: Attacks don't end your turn") .. "|" ..
+		loc("Mines time: 0 seconds"), -amBee, 0)
 
 	SetWind(-75)
 
--- a/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Teamwork.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Teamwork.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -107,11 +107,8 @@
 	if GetGearType(gear) == gtCase then
 		TurnTimeLeft = TurnTimeLeft + 5000
 	end
-
-	if (gear == enemy) and (GameOver == false) then
-		ShowMission(loc("Teamwork"), loc("MISSION SUCCESSFUL"), loc("Congratulations!"), 0, 0)
-		GameOver = true
-	elseif  ( ((gear == player) or (gear == p2)) and (GameOver == false)) then
+	-- Note: The victory sequence is done automatically by Hedgewars
+	if  ( ((gear == player) or (gear == p2)) and (GameOver == false)) then
 		ShowMission(loc("Teamwork"), loc("MISSION FAILED"), loc("Oh no! Just try again!"), -amSkip, 0)
 		GameOver = true
 		SetHealth(p2,0)
--- a/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Teamwork_2.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Scenario/User_Mission_-_Teamwork_2.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -9,7 +9,6 @@
 local Pack = nil
 local help = false
 local GameOver = false
-local skipTime = 0
 
 function onGameInit()
 	Seed = 0
@@ -70,6 +69,13 @@
 	AddGear(1668, 842, gtExplosives, 0, 0, 0, 0)
 	AddGear(1713, 969, gtExplosives, 0, 0, 0, 0)
 	SetWind(90)
+
+	-- The enemy has no weapons and can only skip
+	for i=0, AmmoTypeMax do
+		if i ~= amNothing and i ~= amSkip then
+			AddAmmo(enemy, i, 0)
+		end
+	end
 end
 
 function onGearAdd(gear)
@@ -89,28 +95,12 @@
 	SetAmmo(amDynamite, 0, 0, 0, 1)
 end
 
---[[ This is some hackery to make the enemy hedgehog skip ]]
-function onNewTurn()
-	if CurrentHedgehog == enemy then
-		skipTime = GameTime + 1
-	end
-end
-
-function onGameTick20()
-	if CurrentHedgehog == enemy and skipTime ~= 0 and skipTime < GameTime then
-        	ParseCommand("/skip")
-		skipTime = 0
-	end
-end
-
 function onGearDelete(gear)
 	if gear == Pack then
 		HogSay(CurrentHedgehog, loc("This will certianly come in handy."), SAY_THINK)
 	end
-	if (gear == enemy) and (GameOver == false) then
-		ShowMission(loc("Teamwork 2"), loc("MISSION SUCCESSFUL"), loc("Congratulations!"), 0, 0)
-		GameOver = true
-	elseif ( ((gear == player) or (gear == hlayer)) and (GameOver == false)) then
+	-- Note: The victory sequence is done automatically by Hedgewars
+	if ( ((gear == player) or (gear == hlayer)) and (GameOver == false)) then
 		ShowMission(loc("Teamwork 2"), loc("MISSION FAILED"), loc("Oh no! Just try again!"), -amSkip, 0)
 		GameOver = true
 		SetHealth(hlayer, 0)
--- a/share/hedgewars/Data/Missions/Scenario/User_Mission_-_The_Great_Escape.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Scenario/User_Mission_-_The_Great_Escape.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -80,13 +80,13 @@
 SetHealth(player, 1)
 SetHealth(enemy, 1)
 ------ AMMO CRATE LIST ------
-SpawnAmmoCrate(1632,943,5)
-SpawnAmmoCrate(1723,888,12)
-SpawnAmmoCrate(1915,599,1)
+SpawnAmmoCrate(1632,943,amShotgun)
+SpawnAmmoCrate(1723,888,amFirePunch)
+SpawnAmmoCrate(1915,599,amGrenade)
+SpawnAmmoCrate(1416,913,amBlowTorch)
+SpawnAmmoCrate(1227,640,amPickHammer)
 ------ UTILITY CRATE LIST ------
-SpawnUtilityCrate(1519,945,15)
-SpawnUtilityCrate(1227,640,6)
-SpawnUtilityCrate(1416,913,18)
+SpawnUtilityCrate(1519,945,amParachute)
 ------ END LOADING DATA ------
 
 end
--- a/share/hedgewars/Data/Missions/Scenario/portal.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Scenario/portal.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -128,19 +128,13 @@
 	--UTILITY CRATE--
 	parachute = SpawnUtilityCrate(1670, 1165, amParachute)
 	girder = SpawnUtilityCrate(2101, 1297, amGirder)
-	SpawnUtilityCrate(3965, 625, amBlowTorch)
-	SpawnUtilityCrate(2249, 93, amBlowTorch)
-	SpawnUtilityCrate(2181, 829, amBlowTorch)
-	SpawnUtilityCrate(1820, 567, amBlowTorch)
 	SpawnUtilityCrate(1375, 900, amTeleport)
-	SpawnUtilityCrate(130, 600, amPickHammer)
 	SpawnUtilityCrate(1660,1820, amLaserSight)
 	SpawnUtilityCrate(4070,1840, amLaserSight)
-
+	portalgun = SpawnUtilityCrate(505, 1943, amPortalGun, 1000)
+	extratime = SpawnUtilityCrate(4020, 785, amExtraTime, 2)
 
 	--AMMO CRATE--
-	portalgun = SpawnAmmoCrate(505, 1943, amPortalGun, 1000)
-	extratime = SpawnAmmoCrate(4020, 785, amExtraTime, 2)
 	SpawnAmmoCrate(425, 613, amSnowball)
 	SpawnAmmoCrate(861, 633, amHellishBomb)
 	SpawnAmmoCrate(2510, 623, amSnowball)
@@ -150,6 +144,11 @@
 	SpawnAmmoCrate(3000, 100, amDEagle)
 	SpawnAmmoCrate(2900, 1400, amRope)
 	SpawnAmmoCrate(4025, 1117, amFirePunch)
+	SpawnAmmoCrate(3965, 625, amBlowTorch)
+	SpawnAmmoCrate(2249, 93, amBlowTorch)
+	SpawnAmmoCrate(2181, 829, amBlowTorch)
+	SpawnAmmoCrate(1820, 567, amBlowTorch)
+	SpawnAmmoCrate(130, 600, amPickHammer)
 
 	--HEALTH CRATE--
 	SpawnHealthCrate(2000, 780)
--- a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Bazooka.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Bazooka.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -66,7 +66,7 @@
 	-- The base number for the random number generator
 	Seed = 1
 	-- Game settings and rules
-    EnableGameFlags(gfMultiWeapon, gfOneClanMode, gfSolidLand)
+    EnableGameFlags(gfMultiWeapon, gfOneClanMode, gfSolidLand, gfDisableWind)
     -- Uncommenting this wouldn't do anything
     --EnableGameFlags(gfMultiWeapon, gfOneClanMode, gfSolidLand)
     -- Neither this
@@ -108,6 +108,7 @@
 	SendHealthStatsOff()
 	-- Spawn the first target.
 	spawnTarget()
+	SetWind(-20)
 	
 	-- Show some nice mission goals.
 	-- Parameters are: caption, sub caption, description,
--- a/share/hedgewars/Data/Missions/Training/Basic_Training_-_Rope.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Missions/Training/Basic_Training_-_Rope.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -39,7 +39,7 @@
 	AddCaption( loc( "Victory!" ))
 	if TurnTimeLeft >= 250000 then -- If you very fast, unlock the ahievement "Rope Master!"
 		RopeMaster = true
-		AddCaption( loc( "Achievement obtained: Rope Master!" ),0xffba00ff,capgrpAmmoinfo )
+		AddCaption( string.format(loc( "Achievement gotten: %s"), loc("Rope Master") ),0xffba00ff,capgrpAmmoinfo )
 		PlaySound( sndHomerun )
 	end
 	Objective = true
Binary file share/hedgewars/Data/Scripts/Multiplayer/Construction_Mode.hwp has changed
--- a/share/hedgewars/Data/Scripts/Multiplayer/Construction_Mode.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Construction_Mode.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -1628,6 +1628,8 @@
 		loc("|Cursor: Place crate"))
 	SetAmmoTexts(amDrillStrike, loc("Object Placer"), loc("Construction Mode tool"), loc("This allows you to create and place mines,|sticky mines and barrels anywhere within your|clan's area of influence at the cost of energy.|Up/down: Choose object type|Left/right: Choose timer (for mines)|Cursor: Place object"))
 
+	SetAmmoDescriptionAppendix(amTeleport, loc("It only works in teleportation nodes of your own clan."))
+	
 	sCirc = AddVisualGear(0,0,vgtCircle,0,true)
 	SetVisualGearValues(sCirc, 0, 0, 100, 255, 1, 10, 0, 40, 3, 0x00000000)
 
--- a/share/hedgewars/Data/Scripts/Multiplayer/Frenzy.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Frenzy.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -4,37 +4,36 @@
 -------------------------------------------
 
 HedgewarsScriptLoad("/Scripts/Locale.lua")
-HedgewarsScriptLoad("/Scripts/Tracker.lua")
 
 local cTimer = 0
 local cn = 0
 
-function initialSetup(gear)
-	SetHealth(gear, 75) -- official is 80, but that assumes bazookas/grenades that do 50 damage
-end
+local frenzyAmmos = {
+	amBazooka,
+	amGrenade,
+	amMolotov,
+	amShotgun,
+	amFirePunch,
+	amMine,
+	amJetpack,
+	amBlowTorch,
+	amTeleport,
+	amLowGravity
+}
 
 function showStartingInfo()
 
 	ruleSet = "" ..
-	loc("RULES") .. ": " .. "|" ..
+	loc("RULES:") .. " |" ..
 	loc("Each turn is only ONE SECOND!") .. "|" ..
 	loc("Use your ready time to think.") .. "|" ..
-	loc("Slot keys save time! (F1-F10 by default)") .. "|" ..
-	" |" ..
-	loc("SLOTS") .. ": " .. "|" ..
-	loc("Slot") .. " 1 - " .. loc("Bazooka") .. "|" ..
-	loc("Slot") .. " 2 - " .. loc("Grenade") .. "|" ..
-	loc("Slot") .. " 3 - " .. loc("Shotgun") .. "|" ..
-	loc("Slot") .. " 4 - " .. loc("Shoryuken") .. "|" ..
-	loc("Slot") .. " 5 - " .. loc("Mine") .. "|" ..
-	loc("Slot") .. " 6 - " .. loc("Teleport") .. "|" ..
-	loc("Slot") .. " 7 - " .. loc("Blowtorch") .. "|" ..
-	loc("Slot") .. " 8 - " .. loc("Flying Saucer") .. "|" ..
-	loc("Slot") .. " 9 - " .. loc("Molotov") .. "|" ..
-	loc("Slot") .. " 10 - " .. loc("Low Gravity")
+	loc("Slot keys save time! (F1-F10 by default)") .. "| |"
+	for i=1, #frenzyAmmos do
+		ruleSet = ruleSet .. string.format(loc("Slot %d: %s"), i, GetAmmoName(frenzyAmmos[i])) .. "|"
+	end
 
 	ShowMission(loc("FRENZY"),
-                loc("a frenetic Hedgewars mini-game"),
+                loc("A frenetic Hedgewars mini-game"),
                 ruleSet, 0, 4000)
 
 end
@@ -68,7 +67,6 @@
 
 function onGameStart()
 	showStartingInfo()
-	runOnHogs(initialSetup)
 end
 
 function onSlot(sln)
@@ -87,56 +85,19 @@
 	end
 end
 
+-- Keyboard slot shortcuts
 function ChangeWep(s)
 
-	if s == 0 then
-		SetWeapon(amBazooka)
-	elseif s == 1 then
-		SetWeapon(amGrenade)
-	elseif s == 2 then
-		SetWeapon(amShotgun)
-	elseif s == 3 then
-		SetWeapon(amFirePunch)
-	elseif s == 4 then
-		SetWeapon(amMine)
-	elseif s == 5 then
-		SetWeapon(amTeleport)
-	elseif s == 6 then
-		SetWeapon(amBlowTorch)
-	elseif s == 7 then
-		SetWeapon(amJetpack)
-	elseif s == 8 then
-		SetWeapon(amMolotov)
-	elseif s == 9 then
-		SetWeapon(amLowGravity)
+	if s >= 0 and s <= 9 then
+		SetWeapon(frenzyAmmos[s+1])
 	end
 
 end
 
-function onGearAdd(gear)
-	if GetGearType(gear) == gtHedgehog then
-		trackGear(gear)
+function onAmmoStoreInit()
+	-- Add frenzy ammos
+	for i=1, #frenzyAmmos do
+		SetAmmo(frenzyAmmos[i], 9, 0, 0, 0)
 	end
-end
-
-function onGearDelete(gear)
-	if GetGearType(gear) == gtHedgehog then
-		trackDeletion(gear)
-	end
+	SetAmmo(amSkip, 9, 0, 0, 0)
 end
-
-function onAmmoStoreInit()
-	SetAmmo(amBazooka, 9, 0, 0, 0)
-	SetAmmo(amGrenade, 9, 0, 0, 0)
-	SetAmmo(amMolotov, 9, 0, 0, 0)
-	SetAmmo(amShotgun, 9, 0, 0, 0)
-	--SetAmmo(amFlamethrower, 9, 0, 0, 0) -- this was suggested on hw.org but it's not present on base
-	SetAmmo(amFirePunch, 9, 0, 0, 0)
-	SetAmmo(amMine, 9, 0, 0, 0)
-	--SetAmmo(amCake, 1, 0, 2, 0) -- maybe it's beefcake?
-	SetAmmo(amJetpack, 9, 0, 0, 0)
-	SetAmmo(amBlowTorch, 9, 0, 0, 0)
-	SetAmmo(amTeleport, 9, 0, 0, 0)
-	SetAmmo(amLowGravity, 9, 0, 0, 0)
-	--SetAmmo(amSkipGo, 9, 0, 0, 0) -- not needed with 1s turn time
-end
Binary file share/hedgewars/Data/Scripts/Multiplayer/HedgeEditor.hwp has changed
--- a/share/hedgewars/Data/Scripts/Multiplayer/HedgeEditor.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/HedgeEditor.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -276,6 +276,9 @@
 -- experimental crap
 --local destroyMap = false
 
+-- Special frames in Ammos.png/Ammos_bw.png
+local ammoFrameAirAttack = 63
+
 -----------------------------------------
 -- tracking vars for save/load purposes
 -----------------------------------------
@@ -320,79 +323,78 @@
 local atkArray =
 				{
 
-				{amBazooka, 	"amBazooka",		2},
-				{amBee, 	"amBee",		3},
-				{amMortar, 	"amMortar",		21},
-				{amDrill, 	"amDrill",		28},
-				{amSnowball, 	"amSnowball",		50},
-
-				{amGrenade,	"amGrenade",		0},
-				{amClusterBomb,	"amClusterBomb",	1},
-				{amWatermelon, 	"amWatermelon",		25},
-				{amHellishBomb,	"amHellishBomb",	26},
-				{amMolotov, 	"amMolotov",		39},
-				{amGasBomb, 	"amGasBomb",		43},
-
-				{amShotgun,	"amShotgun",		4},
-				{amDEagle,	"amDEagle",		9},
-				{amSniperRifle,	"amSniperRifle",	37},
-				{amSineGun, 	"amSineGun",		44},
-				{amFlamethrower,"amFlamethrower",	45},
-				{amIceGun, 	"amIceGun",		53},
-
-				{amFirePunch, 	"amFirePunch",		11},
-				{amWhip,	"amWhip",		12},
-				{amBaseballBat, "amBaseballBat",	13},
-				{amKamikaze, 	"amKamikaze",		22},
-				{amSeduction, 	"amSeduction",		24},
-				{amHammer,	"amHammer",		47},
-
-				{amMine, 	"amMine",		8},
-				{amDynamite, 	"amDynamite",		10},
-				{amCake, 	"amCake",		23},
-				{amBallgun, 	"amBallgun",		29},
-				{amRCPlane,	"amRCPlane",		30},
-				{amSMine,	"amSMine",		46},
-
-				{amAirAttack,	"amAirAttack",		15},
-				{amMineStrike,	"amMineStrike",		16},
-				{amNapalm, 	"amNapalm",		27},
-				{amPiano,	"amPiano",		42},
-				{amDrillStrike,	"amDrillStrike",	49},
-				{amAirMine,	"amAirMine",		56},
-
-				{amKnife,	"amKnife",		54},
-
-				{amBirdy,	"amBirdy",		40},
-				{amDuck,	"amDuck",		57},
+				{amBazooka, 	"amBazooka"},
+				{amBee, 	"amBee"},
+				{amMortar, 	"amMortar"},
+				{amDrill, 	"amDrill"},
+				{amSnowball, 	"amSnowball"},
+
+				{amGrenade,	"amGrenade"},
+				{amClusterBomb,	"amClusterBomb"},
+				{amWatermelon, 	"amWatermelon"},
+				{amHellishBomb,	"amHellishBomb"},
+				{amMolotov, 	"amMolotov"},
+				{amGasBomb, 	"amGasBomb"},
+
+				{amShotgun,	"amShotgun"},
+				{amDEagle,	"amDEagle"},
+				{amSniperRifle,	"amSniperRifle"},
+				{amSineGun, 	"amSineGun"},
+				{amFlamethrower,"amFlamethrower"},
+				{amIceGun, 	"amIceGun"},
+
+				{amFirePunch, 	"amFirePunch"},
+				{amWhip,	"amWhip"},
+				{amBaseballBat, "amBaseballBat"},
+				{amKamikaze, 	"amKamikaze"},
+				{amSeduction, 	"amSeduction"},
+				{amHammer,	"amHammer"},
+
+				{amMine, 	"amMine"},
+				{amDynamite, 	"amDynamite"},
+				{amCake, 	"amCake"},
+				{amBallgun, 	"amBallgun"},
+				{amRCPlane,	"amRCPlane"},
+				{amSMine,	"amSMine"},
+
+				{amAirAttack,	"amAirAttack", ammoFrameAirAttack}, -- overwritten icon in Ammos.png
+				{amMineStrike,	"amMineStrike"},
+				{amNapalm, 	"amNapalm"},
+				{amPiano,	"amPiano"},
+				{amDrillStrike,	"amDrillStrike"},
+				{amAirMine,	"amAirMine"},
+
+				{amPickHammer,	"amPickHammer"},
+				{amBlowTorch, 	"amBlowTorch"},
+				{amKnife,	"amKnife"},
+
+				{amBirdy,	"amBirdy"},
+				{amDuck,	"amDuck"},
 
 				}
 
 local utilArray =
 				{
-
-				{amPickHammer,	"amPickHammer",		5},
-				{amBlowTorch, 	"amBlowTorch",		17},
-				{amGirder, 	"amGirder",		18},
-				{amLandGun,	"amLandGun",		52},
-				{amRubber, 	"amRubber",		55},
-
-				{amRope, 	"amRope",		7},
-				{amParachute, 	"amParachute",		14},
-				{amTeleport,	"amTeleport",		19},
-				{amJetpack,	"amJetpack",		38},
-				{amPortalGun,	"amPortalGun",		41},
-
-				{amInvulnerable,"amInvulnerable",	33},
-				{amLaserSight,	"amLaserSight",		35},
-				{amVampiric,	"amVampiric",		36},
-				{amResurrector, "amResurrector",	48},
-				{amTardis, 	"amTardis",		51},
-
-				{amSwitch,	"amSwitch",		20},
-				{amLowGravity, 	"amLowGravity",		31},
-				{amExtraDamage, "amExtraDamage",	32},
-				{amExtraTime,	"amExtraTime",		34},
+				{amGirder, 	"amGirder"},
+				{amLandGun,	"amLandGun"},
+				{amRubber, 	"amRubber"},
+
+				{amRope, 	"amRope"},
+				{amParachute, 	"amParachute"},
+				{amTeleport,	"amTeleport"},
+				{amJetpack,	"amJetpack"},
+				{amPortalGun,	"amPortalGun"},
+
+				{amInvulnerable,"amInvulnerable"},
+				{amLaserSight,	"amLaserSight"},
+				{amVampiric,	"amVampiric"},
+				{amResurrector, "amResurrector"},
+				{amTardis, 	"amTardis"},
+
+				{amSwitch,	"amSwitch"},
+				{amLowGravity, 	"amLowGravity"},
+				{amExtraDamage, "amExtraDamage"},
+				{amExtraTime,	"amExtraTime"},
 
 				}
 
@@ -572,7 +574,7 @@
 			}
 
  local reducedSpriteIDArray = {
-  sprAmRubber, sprAmGirder, sprTargetBee, sprIceTexture, sprHHTelepMask,
+  sprTargetBee, sprAmGirder, sprAmRubber, sprIceTexture, sprHHTelepMask,
   sprAMAmmos, sprAMAmmosBW, sprAMSlot, sprAMCorners, sprTurnsLeft, sprBotlevels,
   sprSpeechCorner, sprSpeechEdge, sprSpeechTail, sprThoughtCorner, sprThoughtEdge, sprThoughtTail,
   sprShoutCorner, sprShoutEdge, sprShoutTail, sprCustom1, sprCustom2, }
@@ -581,7 +583,7 @@
  local reducedSpriteIDArrayFrames
 
  local reducedSpriteTextArray = {
-  "sprAmRubber", "sprAmGirder", "sprTargetBee", "sprIceTexture", "sprHHTelepMask",
+  "sprTargetBee", "sprAmGirder", "sprAmRubber", "sprIceTexture", "sprHHTelepMask",
   "sprAMAmmos", "sprAMAmmosBW", "sprAMSlot",  "sprAMCorners", "sprTurnsLeft", "sprBotlevels",
   "sprSpeechCorner", "sprSpeechEdge", "sprSpeechTail", "sprThoughtCorner", "sprThoughtEdge", "sprThoughtTail",
   "sprShoutCorner", "sprShoutEdge", "sprShoutTail", "sprCustom1", "sprCustom2", }
@@ -764,14 +766,12 @@
 		-- Weapon Crates
 		elseif (specialPointsFlag[i] >= 20) and (specialPointsFlag[i] < (#atkArray+20)) then
 			tempG = SpawnAmmoCrate(specialPointsX[i],specialPointsY[i],atkArray[specialPointsFlag[i]-19][1])
-			setGearValue(tempG,"caseType","ammo")
 			setGearValue(tempG,"contents",atkArray[specialPointsFlag[i]-19][2])
 
 
 		-- Utility Crates
 		elseif (specialPointsFlag[i] >= (#atkArray+20)) and (specialPointsFlag[i] < (#atkArray+20+#utilArray)) then
 			tempG = SpawnUtilityCrate(specialPointsX[i],specialPointsY[i],utilArray[specialPointsFlag[i]-19-#atkArray][1])
-			setGearValue(tempG,"caseType","util")
 			setGearValue(tempG,"contents",utilArray[specialPointsFlag[i]-19-#atkArray][2])
 
 		--79-82 (reserved for future wep crates)
@@ -988,7 +988,13 @@
 		placedTint[pID] = 255 + (255*0x100) + (255*0x10000) + (255*0x1000000) -- A BGR
 	end
 
-	return PlaceSprite(placedX[pID], placedY[pID], placedSprite[pID], placedFrame[pID],
+	-- Special case: Placing amAirAttack of the ammos sprite (since this one is overwritten)
+	local actualDisplayedImage = placedFrame[pID]
+	if (placedSprite[pID] == sprAMAmmos or placedSprite[pID] == sprAMAmmosBW) and (actualDisplayedImage == (amAirAttack - 1)) then
+		actualDisplayedImage = ammoFrameAirAttack
+	end
+
+	return PlaceSprite(placedX[pID], placedY[pID], placedSprite[pID], actualDisplayedImage,
 		placedTint[pID],
 		nil, -- overrite existing land
 		nil, nil, -- this stuff specifies flipping
@@ -1157,16 +1163,13 @@
 	elseif cat[cIndex] == loc("Health Crate Placement Mode") then
 		gear = SpawnHealthCrate(x,y)
 		SetHealth(gear, pMode[pIndex])
-		setGearValue(gear,"caseType","med")
 	elseif cat[cIndex] == loc("Weapon Crate Placement Mode") then
 		gear = SpawnAmmoCrate(x, y, atkArray[pIndex][1])
 		placedSpec[placedCount] = atkArray[pIndex][2]
-		setGearValue(gear,"caseType","ammo")
 		setGearValue(gear,"contents",atkArray[pIndex][2])
 	elseif cat[cIndex] == loc("Utility Crate Placement Mode") then
 		gear = SpawnUtilityCrate(x, y, utilArray[pIndex][1])
 		placedSpec[placedCount] = utilArray[pIndex][2]
-		setGearValue(gear,"caseType","util")
 		setGearValue(gear,"contents",utilArray[pIndex][2])
 	elseif cat[cIndex] == loc("Barrel Placement Mode") then
 		gear = AddGear(x, y, gtExplosives, 0, 0, 0, 0)
@@ -1732,7 +1735,8 @@
 
 		table.insert(previewDataList, "	PreviewPlacedGear(" .. GetX(gear) ..", " ..	GetY(gear) .. ")")
 
-		if (GetHealth(gear) ~= nil) then
+		-- Health crate
+		if band(GetGearPos(gear), 0x2) ~= 0 then
 
 			temp = 	"	tempG = SpawnHealthCrate(" ..
 				GetX(gear) ..", " ..
@@ -1749,7 +1753,8 @@
 			elseif	GetHealth(gear) == 100 then specialFlag = 12
 			end
 
-		elseif getGearValue(gear,"caseType") == "ammo" then
+		-- Ammo crate
+		elseif band(GetGearPos(gear), 0x1) ~= 0 then
 
 			arrayList = wepCrateList
 			temp = 	"	tempG = SpawnAmmoCrate(" ..
@@ -1766,12 +1771,11 @@
 				end
 			end
 
-			--dammit, we probably need two more entries if we want to allow editing of existing maps
-			table.insert(wepCrateList, "	setGearValue(tempG, \"caseType\", \"" .. getGearValue(gear,"caseType") .. "\")")
+			--dammit, we probably need more entries if we want to allow editing of existing maps
 			table.insert(wepCrateList, "	setGearValue(tempG, \"contents\", \"" .. getGearValue(gear,"contents") .. "\")")
 
-
-		elseif getGearValue(gear,"caseType") == "util" then
+		-- Utility crate
+		elseif band(GetGearPos(gear), 0x4) ~= 0 then
 
 			arrayList = utilCrateList
 			temp = 	"	tempG = SpawnUtilityCrate(" ..
@@ -1788,8 +1792,7 @@
 				end
 			end
 
-			--dammit, we probably need two more entries if we want to allow editing of existing maps
-			table.insert(utilCrateList, "	setGearValue(tempG, \"caseType\", \"" .. getGearValue(gear,"caseType") .. "\")")
+			--dammit, we probably need more entries if we want to allow editing of existing maps
 			table.insert(utilCrateList, "	setGearValue(tempG, \"contents\", \"" .. getGearValue(gear,"contents") .. "\")")
 
 		end
@@ -1953,21 +1956,6 @@
 	WriteLnToConsole("local hhs = {}")
 	WriteLnToConsole("")
 
-	WriteLnToConsole("local wepArray = {")
-	WriteLnToConsole("		amBazooka, amBee, amMortar, amDrill, amSnowball,")
-	WriteLnToConsole("		amGrenade, amClusterBomb, amMolotov, amWatermelon, amHellishBomb, amGasBomb,")
-	WriteLnToConsole("		amShotgun, amDEagle, amSniperRifle, amSineGun, amLandGun, amIceGun,")
-	WriteLnToConsole("		amFirePunch, amWhip, amBaseballBat, amKamikaze, amSeduction, amHammer,")
-	WriteLnToConsole("		amMine, amDynamite, amCake, amBallgun, amRCPlane, amSMine, amAirMine,")
-	WriteLnToConsole("		amAirAttack, amMineStrike, amDrillStrike, amNapalm, amPiano, amBirdy,")
-	WriteLnToConsole("		amBlowTorch, amPickHammer, amGirder, amRubber, amPortalGun,")
-	WriteLnToConsole("		amRope, amParachute, amTeleport, amJetpack,")
-	WriteLnToConsole("		amInvulnerable, amLaserSight, amVampiric,")
-	WriteLnToConsole("		amLowGravity, amExtraDamage, amExtraTime, amResurrector, amTardis, amSwitch")
-	WriteLnToConsole("	}")
-	WriteLnToConsole("")
-
-
 	SaveConfigData()
 
 
@@ -2024,13 +2012,17 @@
 
 	for i = 0, (placedCount-1) do
 		if placedType[i] == loc("Waypoint Editing Mode") then
+			--[[ TODO/FIXME: Somehow incorporate the waypoints in an actual useful manner.
+			The functions AddWayPoint and PreviewWayPoint do not exist and will thus be commented-out
+			in the output code. They are added anyway so the user sees the coordinates
+			]]
 			table.insert(waypointList,
-			"	AddWayPoint(" ..
+			"--	AddWayPoint(" ..
 				placedX[i] ..", " ..
 				placedY[i] ..")"
 				)
 			table.insert(hFlagList, "	" .. placedX[i] .. " " .. placedY[i] .. " " .. "0")
-			table.insert(previewDataList, "	PreviewWayPoint(" .. placedX[i] ..", " ..	placedY[i] .. ")")
+			table.insert(previewDataList, "--	PreviewWayPoint(" .. placedX[i] ..", " ..	placedY[i] .. ")")
 		end
 	end
 
@@ -2329,8 +2321,10 @@
 	WriteLnToConsole("function onAmmoStoreInit()")
 	WriteLnToConsole("")
 
-	WriteLnToConsole("	for i = 1, #wepArray do")
-	WriteLnToConsole("		SetAmmo(wepArray[i], 0, 0, 0, 1)")
+	WriteLnToConsole("	for i = 0, AmmoTypeMax do")
+	WriteLnToConsole("		if i ~= amNothing then")
+	WriteLnToConsole("			SetAmmo(i, 0, 0, 0, 1)")
+	WriteLnToConsole("		end")
 	WriteLnToConsole("	end")
 	WriteLnToConsole("")
 	WriteLnToConsole("	SetAmmo(amSkip, 9, 0, 0, 0)")
@@ -2592,7 +2586,7 @@
 				loc("Change Placement Mode: [Up], [Down]") .. "|" ..
 				loc("Toggle Help: [Precise]+[1]") .. "|" ..
 				loc("Toggle Gear Information: [Precise]+[3]") .. "|" ..
-				"", -amMine, 60000
+				"", 9, 60000
 				)
 		hedgeEditorMissionPanelShown = false
 
@@ -2830,9 +2824,8 @@
 				dSprite = sprBotlevels--sprMineOff
 				dFrame = 1
 			elseif (cat[cIndex] == loc("Dud Mine Placement Mode")) then
-				-- TODO: Use dud mine sprite instead of sprite of normal mine
-				dSprite = sprBotlevels--sprMineOff
-				dFrame = 1
+				dSprite = sprBotlevels--sprMineDead
+				dFrame = 3
 			elseif (cat[cIndex] == loc("Sticky Mine Placement Mode")) then
 				dSprite = sprBotlevels--sprSMineOff
 				dFrame = 2
@@ -2854,6 +2847,10 @@
 			elseif (cat[cIndex] == loc("Sprite Placement Mode")) then
 				dSprite = reducedSpriteIDArray[pIndex]
 				dFrame = sFrame
+				if ((dSprite == sprAMAmmos) or (dSprite == sprAMAmmosBW)) and (dFrame == (amAirAttack - 1)) then
+					-- Special case: Air attack icon of ammos sprite needs to be fixed (since this icon is overwritten)
+					dFrame = ammoFrameAirAttack
+				end
 			else
 				dCol = 0xFFFFFF00
 				dSprite = sprArrow
@@ -2882,8 +2879,14 @@
 				end
 
 				tSprCol = 0xFFFFFFFF
-				tempFrame = tArr[pIndex][3]
-
+				-- Get ammo icon
+				if tArr[pIndex][3] then
+					-- Overwritten ammo icon
+					tempFrame = tArr[pIndex][3]
+				else
+					-- Use default ammo icon
+					tempFrame = tArr[pIndex][1] - 1
+				end
 			end
 
 		else
@@ -2893,10 +2896,10 @@
 		end
 
 		SetVisualGearValues(crateSprite, CursorX+xDisplacement, CursorY+yDisplacement, 0, 0, dAngle, tempFrame, 1000, sprAMAmmos, 1000, tSprCol)
-		SetVisualGearValues(tSpr[1], CursorX+xDisplacement-2, CursorY+yDisplacement-2, 0, 0, dAngle, 10, 1000, sprTarget, 1000, tSprCol)
-		SetVisualGearValues(tSpr[2], CursorX+xDisplacement-2, CursorY+yDisplacement+2, 0, 0, dAngle, 10, 1000, sprTarget, 1000, tSprCol)
-		SetVisualGearValues(tSpr[3], CursorX+xDisplacement+2, CursorY+yDisplacement-2, 0, 0, dAngle, 10, 1000, sprTarget, 1000, tSprCol)
-		SetVisualGearValues(tSpr[4], CursorX+xDisplacement+2, CursorY+yDisplacement+2, 0, 0, dAngle, 10, 1000, sprTarget, 1000, tSprCol)
+		SetVisualGearValues(tSpr[1], CursorX+xDisplacement-2, CursorY+yDisplacement-2, 0, 0, dAngle, 1, 1000, sprTarget, 1000, tSprCol)
+		SetVisualGearValues(tSpr[2], CursorX+xDisplacement-2, CursorY+yDisplacement+2, 0, 0, dAngle, 1, 1000, sprTarget, 1000, tSprCol)
+		SetVisualGearValues(tSpr[3], CursorX+xDisplacement+2, CursorY+yDisplacement-2, 0, 0, dAngle, 1, 1000, sprTarget, 1000, tSprCol)
+		SetVisualGearValues(tSpr[4], CursorX+xDisplacement+2, CursorY+yDisplacement+2, 0, 0, dAngle, 1, 1000, sprTarget, 1000, tSprCol)
 
 
 		if genTimer >= 100 then
@@ -3364,7 +3367,7 @@
 	end
 
 	reducedSpriteIDArrayFrames = {
-		4, 8, 1, 1, 1,
+		1, 8, 4, 1, 1,
 		AmmoTypeMax, AmmoTypeMax, 3, 4, 8, 1,
 		1, 1, 1, 1, 1, 1,
 		1, 1, 1, 1, 1,
--- a/share/hedgewars/Data/Scripts/Multiplayer/Highlander.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Highlander.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -261,8 +261,8 @@
 			end
 		end
 
-        PlaySound(sndShotgunReload);
         if dspl and ammolist ~= '' then
+            PlaySound(sndShotgunReload);
             AddCaption(ammolist, color, capgrpAmmoinfo)
         end
 	end
--- a/share/hedgewars/Data/Scripts/Multiplayer/Mutant.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Mutant.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -152,6 +152,8 @@
 
 function onGameStart()
     SendHealthStatsOff()
+    SendRankingStatsOff()
+    SendAchievementsStatsOff()
     trackTeams()
     teamScan()
     runOnHogs(saveStuff)
@@ -321,7 +323,7 @@
                         SetHealth(mutant,0)
                         mt_hurt= false
                         setGearValue(mutant,"SelfDestruct",true)
-                        TurnTimeLeft = 0
+                        EndTurn()
                     end
             end
     end
@@ -409,7 +411,7 @@
     if gameOver then
         SendStat(siGraphTitle, loc("Score graph"))
 
-        TurnTimeLeft = 0
+        EndTurn(true)
 
         teamsSorted = {}
  
@@ -465,9 +467,6 @@
             SendStat(siPlayerKills, getTeamValue(teamsSorted[i], "Score"), teamsSorted[i])
         end
 
-        AddCaption(string.format(loc("%s wins!"), winTeam), 0xFFFFFFFF, capgrpGameState )
-        SendStat(siGameResult, string.format("%s wins!", winTeam))
-
         ShowMission(    loc("Mutant"),
                         loc("Final result"),
                         string.format(loc("Winner: %s"), winTeam) .. "| |" .. loc("Scores:") .. " |" ..
@@ -540,7 +539,7 @@
 
     AddCaption(string.format(loc("%s has mutated! +2 points"), getGearValue(gear, "Name")), GetClanColor(GetHogClan(gear)), capgrpMessage)
 
-    TurnTimeLeft=0
+    EndTurn(true)
 
     AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false)
     AddVisualGear(GetX(gear), GetY(gear), vgtSmokeRing, 0, false)
@@ -751,11 +750,6 @@
         end
         AddVisualGear(GetX(gear), GetY(gear), vgtBigExplosion, 0, false)
         trackDeletion(gear)
-
-        -- End game properly when only the winner remains
-        if gameOver and numhhs == 1 then
-            EndGame()
-        end
     elseif GetGearType(gear) == gtCase then
         -- Check if a crate has been collected
         if band(GetGearMessage(gear), gmDestroy) ~= 0 and CurrentHedgehog ~= nil then
Binary file share/hedgewars/Data/Scripts/Multiplayer/Racer.hwp has changed
--- a/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Racer.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -434,9 +434,6 @@
 
         -- end game if its at round limit
         if roundNumber >= roundLimit then
-                gameOver = true
-                TurnTimeLeft = 10000000
-
                 -- Sort the scores for the ranking list
                 local unfinishedArray = {}
                 local sortedTeams = {}
@@ -473,8 +470,17 @@
                         SendStat(siCustomAchievement, loc("Maybe you should try easier waypoints next time."))
                 end
 
-                -- Game over
-                EndGame()
+		-- Kill all the losers
+		for i = 0, (numhhs-1) do
+			if GetHogClan(hhs[i]) ~= bestClan then
+				SetEffect(hhs[i], heResurrectable, 0)
+				SetHealth(hhs[i],0)
+			end
+		end
+
+		gameOver = true
+		EndTurn(true)
+
         end
 
 end
@@ -548,7 +554,10 @@
 
 
 function onGameStart()
+	SendGameResultOff()
+	SendRankingStatsOff()
         SendHealthStatsOff()
+	SendAchievementsStatsOff()
 
         roundN = 0
         lastRound = TotalRounds
--- a/share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Space_Invasion.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -740,20 +740,21 @@
 		statusText = loc("Status Update")
 		scoreText = loc("Team scores:")
 	end
+	local displayTime
+	if roundNumber >= roundLimit then
+		displayTime = 20000
+	else
+		displayTime = 1
+	end
 	ShowMission(	loc("Space Invasion"),
 			statusText,
 			string.format(loc("Rounds complete: %d/%d"), roundNumber, roundLimit) .. "| " .. "|" ..
-			scoreText .. " |" ..entireC, 4, 1)
+			scoreText .. " |" ..entireC, 4, displayTime)
 
 	if roundNumber >= roundLimit then
 		local winnerTeam = teamStats[1].name
-		local victorySoundPlayed = false
 		for i = 0, (numhhs-1) do
 			if GetHogTeamName(hhs[i]) == winnerTeam then
-				if not victorySoundPlayer then
-					PlaySound(sndVictory, hhs[i])
-					victorySoundPlayed = true
-				end
 				SetState(hhs[i], bor(GetState(hhs[i]), gstWinner))
 			end
 		end
@@ -898,11 +899,19 @@
 			end
 		end
 
+		-- Kill off all the losers
+		for i = 0, (numhhs-1) do
+			if GetHogClan(hhs[i]) ~= bestClan then
+				SetEffect(hhs[i], heResurrectable, 0)
+				SetHealth(hhs[i],0)
+			end
+		end
+
+		-- Game over
 		gameOver = true
 		EndTurn(true)
 		TimeLeft = 0
 		SendStat(siGraphTitle, "Score graph")
-		EndGame()
 	end
 end
 
@@ -1228,6 +1237,9 @@
 end
 
 function onGameStart()
+	SendGameResultOff()
+	SendRankingStatsOff()
+	SendAchievementsStatsOff()
 	SendHealthStatsOff()
 
 	ShowMission	(
--- a/share/hedgewars/Data/Scripts/Multiplayer/TechRacer.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/TechRacer.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -460,9 +460,6 @@
 
         -- end game if its at round limit
         if roundNumber >= roundLimit then
-                gameOver = true
-                TurnTimeLeft = 10000000
-
                 -- Sort the scores for the ranking list
                 local unfinishedArray = {}
                 local sortedTeams = {}
@@ -498,8 +495,16 @@
                         SendStat(siCustomAchievement, loc("Maybe you should try an easier TechRacer map."))
                 end
 
-                -- Game over
-                EndGame()
+		-- Kill all the losers
+		for i = 0, (numhhs-1) do
+			if GetHogClan(hhs[i]) ~= bestClan then
+				SetEffect(hhs[i], heResurrectable, 0)
+				SetHealth(hhs[i],0)
+			end
+		end
+
+		gameOver = true
+		EndTurn(true)
         end
 
 end
@@ -956,6 +961,9 @@
 end
 
 function onGameStart()
+	SendGameResultOff()
+	SendRankingStatsOff()
+	SendAchievementsStatsOff()
 	SendHealthStatsOff()
 
 		trackTeams()
--- a/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -97,6 +97,7 @@
 		SetAmmo(amSeduction, 9, 0, 0, 0)
 		SetAmmo(amResurrector, 1, 0, 0, 0)
 		SetAmmo(amInvulnerable, 1, 0, 0, 0)
+        SetAmmo(amLowGravity, 1, 0, 0, 0)
 	elseif hogIndex == 6 then
 		SetAmmo(amFlamethrower, 1, 0, 0, 0)
 		SetAmmo(amMolotov, 1, 0, 0, 0)
--- a/share/hedgewars/Data/Scripts/Multiplayer/Tumbler.lua	Sat Apr 29 23:45:14 2017 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Tumbler.lua	Sat Apr 29 23:49:39 2017 +0200
@@ -356,7 +356,7 @@
 
 			barrelsEaten = barrelsEaten + 1
 			if barrelsEaten == 5 then
-				AddCaption(loc("Achievement obtained: Barrel Eater!"),0xffba00ff,capgrpMessage2)
+				AddCaption(string.format(loc("Achievement gotten: %s"), loc("Barrel Eater")),0xffba00ff,capgrpMessage2)
 			end
 
 		elseif (GetGearType(gear) == gtMine) then
@@ -368,7 +368,7 @@
 
 			minesEaten = minesEaten + 1
 			if minesEaten == 5 then
-				AddCaption(loc("Achievement obtained: Mine Eater!"),0xffba00ff,capgrpMessage2)
+				AddCaption(string.format(loc("Achievement gotten: %s"), loc("Mine Eater")),0xffba00ff,capgrpMessage2)
 			end
 
 		end