merge physfslayer in default
authorkoda
Wed, 27 Feb 2013 16:12:57 +0100
changeset 8593 9d1d0fa8db02
parent 8591 9afb44f030b6 (diff)
parent 8558 e96bf10216ef (current diff)
child 8595 d2940421d3d4
merge physfslayer in default
.hgignore
misc/physfs/Android.mk
misc/physfs/CMakeLists.txt
misc/physfs/Xcode/Physfs.xcodeproj/project.pbxproj
misc/physfs/Xcode/Physfs_Prefix.pch
misc/physfs/extras/hwpacksmounter.c
misc/physfs/extras/hwpacksmounter.h
misc/physfs/extras/physfslualoader.c
misc/physfs/extras/physfsrwops.c
misc/physfs/extras/physfsrwops.h
misc/physfs/src/Android.mk
misc/physfs/src/archiver_dir.c
misc/physfs/src/archiver_grp.c
misc/physfs/src/archiver_hog.c
misc/physfs/src/archiver_iso9660.c
misc/physfs/src/archiver_lzma.c
misc/physfs/src/archiver_mvl.c
misc/physfs/src/archiver_qpak.c
misc/physfs/src/archiver_unpacked.c
misc/physfs/src/archiver_wad.c
misc/physfs/src/archiver_zip.c
misc/physfs/src/physfs.c
misc/physfs/src/physfs.h
misc/physfs/src/physfs_byteorder.c
misc/physfs/src/physfs_casefolding.h
misc/physfs/src/physfs_internal.h
misc/physfs/src/physfs_miniz.h
misc/physfs/src/physfs_platforms.h
misc/physfs/src/physfs_unicode.c
misc/physfs/src/platform_beos.cpp
misc/physfs/src/platform_macosx.c
misc/physfs/src/platform_posix.c
misc/physfs/src/platform_unix.c
misc/physfs/src/platform_windows.c
--- a/.hgignore	Mon Feb 25 19:48:35 2013 +0100
+++ b/.hgignore	Wed Feb 27 16:12:57 2013 +0100
@@ -59,4 +59,5 @@
 glob:*.depends
 glob:tools/build_windows_koda.bat
 glob:share/hedgewars/Data/misc/hwengine.desktop
-
+glob:*.exe
+glob:_CPack_Packages/
--- a/QTfrontend/hwform.cpp	Mon Feb 25 19:48:35 2013 +0100
+++ b/QTfrontend/hwform.cpp	Wed Feb 27 16:12:57 2013 +0100
@@ -350,6 +350,7 @@
         }
     }
 
+    ui.Pages->setCurrentIndex(ID_PAGE_INFO);
     PagesStack.push(ID_PAGE_MAIN);
     ((AbstractPage*)ui.Pages->widget(ID_PAGE_MAIN))->triggerPageEnter();
     GoBack();
@@ -1234,13 +1235,12 @@
             hwnet, SLOT(askRoomsList()));
 
 // room status stuff
-// not queued because creates new signal/slot connection
     connect(hwnet, SIGNAL(roomMaster(bool)),
-            this, SLOT(NetGameChangeStatus(bool)));
+            this, SLOT(NetGameChangeStatus(bool)), Qt::QueuedConnection);
 
 // net page stuff
     connect(hwnet, SIGNAL(roomNameUpdated(const QString &)),
-            ui.pageNetGame, SLOT(setRoomName(const QString &)));
+            ui.pageNetGame, SLOT(setRoomName(const QString &)), Qt::QueuedConnection);
     connect(hwnet, SIGNAL(chatStringFromNet(const QString&)),
             ui.pageNetGame->chatWidget, SLOT(onChatString(const QString&)), Qt::QueuedConnection);
 
@@ -1731,6 +1731,7 @@
     ui.pageNetGame->setMasterMode(true);
     ui.pageNetGame->restrictJoins->setChecked(false);
     ui.pageNetGame->restrictTeamAdds->setChecked(false);
+    ui.pageNetGame->restrictUnregistered->setChecked(false);
     ui.pageNetGame->pGameCFG->GameSchemes->setModel(ammoSchemeModel);
     ui.pageNetGame->pGameCFG->setMaster(true);
     ui.pageNetGame->pNetTeamsWidget->setInteractivity(true);
@@ -1743,6 +1744,7 @@
         ui.pageNetGame->leRoomName->disconnect(hwnet);
         ui.pageNetGame->restrictJoins->disconnect(hwnet);
         ui.pageNetGame->restrictTeamAdds->disconnect(hwnet);
+        ui.pageNetGame->restrictUnregistered->disconnect(hwnet);
         ui.pageNetGame->disconnect(hwnet, SLOT(updateRoomName(const QString&)));
 
         ui.pageNetGame->setRoomName(hwnet->getRoom());
@@ -1751,6 +1753,7 @@
         connect(ui.pageNetGame, SIGNAL(askForUpdateRoomName(const QString &)), hwnet, SLOT(updateRoomName(const QString &)));
         connect(ui.pageNetGame->restrictJoins, SIGNAL(triggered()), hwnet, SLOT(toggleRestrictJoins()));
         connect(ui.pageNetGame->restrictTeamAdds, SIGNAL(triggered()), hwnet, SLOT(toggleRestrictTeamAdds()));
+        connect(ui.pageNetGame->restrictUnregistered, SIGNAL(triggered()), hwnet, SLOT(toggleRegisteredOnly()));
         connect(ui.pageNetGame->pGameCFG->GameSchemes->model(),
                 SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
                 ui.pageNetGame->pGameCFG,
--- a/QTfrontend/net/newnetclient.cpp	Mon Feb 25 19:48:35 2013 +0100
+++ b/QTfrontend/net/newnetclient.cpp	Wed Feb 27 16:12:57 2013 +0100
@@ -63,6 +63,8 @@
     connect(&NetSocket, SIGNAL(disconnected()), this, SLOT(OnDisconnect()));
     connect(&NetSocket, SIGNAL(error(QAbstractSocket::SocketError)), this,
             SLOT(displayError(QAbstractSocket::SocketError)));
+
+    connect(this, SIGNAL(messageProcessed()), this, SLOT(ClientRead()), Qt::QueuedConnection);
 }
 
 HWNewNet::~HWNewNet()
@@ -186,6 +188,8 @@
         {
             ParseCmd(cmdbuf);
             cmdbuf.clear();
+            emit messageProcessed();
+            return ;
         }
         else
             cmdbuf << s;
@@ -486,9 +490,9 @@
                 emit connected();
             }
 
+            m_playersModel->addPlayer(lst[i]);
             emit nickAddedLobby(lst[i], false);
             emit chatStringLobby(lst[i], tr("%1 *** %2 has joined").arg('\x03').arg("|nick|"));
-            m_playersModel->addPlayer(lst[i]);
         }
         return;
     }
@@ -632,9 +636,9 @@
                     emit configAsked();
             }
 
+            m_playersModel->playerJoinedRoom(lst[i]);
             emit nickAdded(lst[i], isChief && (lst[i] != mynick));
             emit chatStringFromNet(tr("%1 *** %2 has joined the room").arg('\x03').arg(lst[i]));
-            m_playersModel->playerJoinedRoom(lst[i]);
         }
         return;
     }
@@ -978,6 +982,11 @@
     RawSendNet(QString("TOGGLE_RESTRICT_TEAMS"));
 }
 
+void HWNewNet::toggleRegisteredOnly()
+{
+    RawSendNet(QString("TOGGLE_REGISTERED_ONLY"));
+}
+
 void HWNewNet::clearAccountsCache()
 {
     RawSendNet(QString("CLEAR_ACCOUNTS_CACHE"));
--- a/QTfrontend/net/newnetclient.h	Mon Feb 25 19:48:35 2013 +0100
+++ b/QTfrontend/net/newnetclient.h	Wed Feb 27 16:12:57 2013 +0100
@@ -131,6 +131,8 @@
 
         void setMyReadyStatus(bool isReady);
 
+        void messageProcessed();
+
     public slots:
         void ToggleReady();
         void chatLineToNet(const QString& str);
@@ -161,6 +163,7 @@
         void startGame();
         void toggleRestrictJoins();
         void toggleRestrictTeamAdds();
+        void toggleRegisteredOnly();
         void partRoom();
         void clearAccountsCache();
         void getBanList();
--- a/QTfrontend/ui/page/pagenetgame.cpp	Mon Feb 25 19:48:35 2013 +0100
+++ b/QTfrontend/ui/page/pagenetgame.cpp	Wed Feb 27 16:12:57 2013 +0100
@@ -170,8 +170,11 @@
     restrictJoins->setCheckable(true);
     restrictTeamAdds = new QAction(QAction::tr("Restrict Team Additions"), menu);
     restrictTeamAdds->setCheckable(true);
+    restrictUnregistered = new QAction(QAction::tr("Restrict Unregistered Players Join"), menu);
+    restrictUnregistered->setCheckable(true);
     menu->addAction(restrictJoins);
     menu->addAction(restrictTeamAdds);
+    menu->addAction(restrictUnregistered);
 
     BtnMaster->setMenu(menu);
 
--- a/QTfrontend/ui/page/pagenetgame.h	Mon Feb 25 19:48:35 2013 +0100
+++ b/QTfrontend/ui/page/pagenetgame.h	Wed Feb 27 16:12:57 2013 +0100
@@ -49,6 +49,7 @@
 
         QAction * restrictJoins;
         QAction * restrictTeamAdds;
+        QAction * restrictUnregistered;
 
         HWChatWidget* chatWidget;
 
--- a/QTfrontend/ui/widget/themeprompt.cpp	Mon Feb 25 19:48:35 2013 +0100
+++ b/QTfrontend/ui/widget/themeprompt.cpp	Wed Feb 27 16:12:57 2013 +0100
@@ -162,4 +162,4 @@
 {
     filterModel->setFilterFixedString(text);
     list->setCurrentIndex(filterModel->index(0, 0));
-}
\ No newline at end of file
+}
--- a/gameServer/Actions.hs	Mon Feb 25 19:48:35 2013 +0100
+++ b/gameServer/Actions.hs	Wed Feb 27 16:12:57 2013 +0100
@@ -32,68 +32,9 @@
 import ConfigFile
 import EngineInteraction
 
-data Action =
-    AnswerClients ![ClientChan] ![B.ByteString]
-    | SendServerMessage
-    | SendServerVars
-    | MoveToRoom RoomIndex
-    | MoveToLobby B.ByteString
-    | RemoveTeam B.ByteString
-    | SendTeamRemovalMessage B.ByteString
-    | RemoveRoom
-    | FinishGame
-    | UnreadyRoomClients
-    | JoinLobby
-    | ProtocolError B.ByteString
-    | Warning B.ByteString
-    | NoticeMessage Notice
-    | ByeClient B.ByteString
-    | KickClient ClientIndex
-    | KickRoomClient ClientIndex
-    | BanClient NominalDiffTime B.ByteString ClientIndex
-    | BanIP B.ByteString NominalDiffTime B.ByteString
-    | BanNick B.ByteString NominalDiffTime B.ByteString
-    | BanList
-    | Unban B.ByteString
-    | ChangeMaster (Maybe ClientIndex)
-    | RemoveClientTeams
-    | ModifyClient (ClientInfo -> ClientInfo)
-    | ModifyClient2 ClientIndex (ClientInfo -> ClientInfo)
-    | ModifyRoomClients (ClientInfo -> ClientInfo)
-    | ModifyRoom (RoomInfo -> RoomInfo)
-    | ModifyServerInfo (ServerInfo -> ServerInfo)
-    | AddRoom B.ByteString B.ByteString
-    | SendUpdateOnThisRoom
-    | CheckRegistered
-    | ClearAccountsCache
-    | ProcessAccountInfo AccountInfo
-    | AddClient ClientInfo
-    | DeleteClient ClientIndex
-    | PingAll
-    | StatsAction
-    | RestartServer
-    | AddNick2Bans B.ByteString B.ByteString UTCTime
-    | AddIP2Bans B.ByteString B.ByteString UTCTime
-    | CheckBanned Bool
-    | SaveReplay
-    | Stats
-    | CheckRecord
-    | CheckFailed B.ByteString
-    | CheckSuccess [B.ByteString]
-
 
 type CmdHandler = [B.ByteString] -> Reader (ClientIndex, IRnC) [Action]
 
-instance NFData Action where
-    rnf (AnswerClients chans msg) = chans `deepseq` msg `deepseq` ()
-    rnf a = a `seq` ()
-
-#if __GLASGOW_HASKELL__ < 706
-instance NFData B.ByteString
-#endif
-
-instance NFData (Chan a)
-
 
 othersChans :: StateT ServerState IO [ClientChan]
 othersChans = do
@@ -461,8 +402,12 @@
             when (not b) $ (if c then checkerLogin else playerLogin) passwd isAdmin
         Guest -> do
             b <- isBanned
+            c <- client's isChecker
             when (not b) $
-                processAction JoinLobby
+                if c then
+                    checkerLogin "" False
+                    else
+                    processAction JoinLobby
         Admin -> do
             mapM_ processAction [ModifyClient (\cl -> cl{isAdministrator = True}), JoinLobby]
             chan <- client's sendChan
@@ -594,6 +539,7 @@
     when (not $ ci `Set.member` rc)
         $ processAction $ ModifyServerInfo (\s -> s{bans = BanByIP ip reason expiring : bans s})
 
+
 processAction (CheckBanned byIP) = do
     clTime <- client's connectTime
     clNick <- client's nick
@@ -613,6 +559,7 @@
         getBanReason (BanByIP _ msg _) = msg
         getBanReason (BanByNick _ msg _) = msg
 
+
 processAction PingAll = do
     rnc <- gets roomsClients
     io (allClientsM rnc) >>= mapM_ (kickTimeouted rnc)
--- a/gameServer/CoreTypes.hs	Mon Feb 25 19:48:35 2013 +0100
+++ b/gameServer/CoreTypes.hs	Wed Feb 27 16:12:57 2013 +0100
@@ -1,4 +1,4 @@
-{-# LANGUAGE OverloadedStrings, DeriveDataTypeable #-}
+{-# LANGUAGE CPP, OverloadedStrings, DeriveDataTypeable #-}
 module CoreTypes where
 
 import Control.Concurrent
@@ -12,9 +12,70 @@
 import Control.Exception
 import Data.Typeable
 import Data.TConfig
+import Control.DeepSeq
 -----------------------
 import RoomsAndClients
 
+
+#if __GLASGOW_HASKELL__ < 706
+instance NFData B.ByteString
+#endif
+
+instance NFData (Chan a)
+
+instance NFData Action where
+    rnf (AnswerClients chans msg) = chans `deepseq` msg `deepseq` ()
+    rnf a = a `seq` ()
+
+data Action =
+    AnswerClients ![ClientChan] ![B.ByteString]
+    | SendServerMessage
+    | SendServerVars
+    | MoveToRoom RoomIndex
+    | MoveToLobby B.ByteString
+    | RemoveTeam B.ByteString
+    | SendTeamRemovalMessage B.ByteString
+    | RemoveRoom
+    | FinishGame
+    | UnreadyRoomClients
+    | JoinLobby
+    | ProtocolError B.ByteString
+    | Warning B.ByteString
+    | NoticeMessage Notice
+    | ByeClient B.ByteString
+    | KickClient ClientIndex
+    | KickRoomClient ClientIndex
+    | BanClient NominalDiffTime B.ByteString ClientIndex
+    | BanIP B.ByteString NominalDiffTime B.ByteString
+    | BanNick B.ByteString NominalDiffTime B.ByteString
+    | BanList
+    | Unban B.ByteString
+    | ChangeMaster (Maybe ClientIndex)
+    | RemoveClientTeams
+    | ModifyClient (ClientInfo -> ClientInfo)
+    | ModifyClient2 ClientIndex (ClientInfo -> ClientInfo)
+    | ModifyRoomClients (ClientInfo -> ClientInfo)
+    | ModifyRoom (RoomInfo -> RoomInfo)
+    | ModifyServerInfo (ServerInfo -> ServerInfo)
+    | AddRoom B.ByteString B.ByteString
+    | SendUpdateOnThisRoom
+    | CheckRegistered
+    | ClearAccountsCache
+    | ProcessAccountInfo AccountInfo
+    | AddClient ClientInfo
+    | DeleteClient ClientIndex
+    | PingAll
+    | StatsAction
+    | RestartServer
+    | AddNick2Bans B.ByteString B.ByteString UTCTime
+    | AddIP2Bans B.ByteString B.ByteString UTCTime
+    | CheckBanned Bool
+    | SaveReplay
+    | Stats
+    | CheckRecord
+    | CheckFailed B.ByteString
+    | CheckSuccess [B.ByteString]
+
 type ClientChan = Chan [B.ByteString]
 
 data CheckInfo =
@@ -47,7 +108,8 @@
         isKickedFromServer :: Bool,
         clientClan :: !(Maybe B.ByteString),
         checkInfo :: Maybe CheckInfo,
-        teamsInGame :: Word
+        teamsInGame :: Word,
+        actionsPending :: [Action]
     }
 
 instance Eq ClientInfo where
--- a/gameServer/EngineInteraction.hs	Mon Feb 25 19:48:35 2013 +0100
+++ b/gameServer/EngineInteraction.hs	Wed Feb 27 16:12:57 2013 +0100
@@ -90,10 +90,10 @@
         initHealth = scheme !! 27
         teamSetup :: TeamInfo -> [B.ByteString]
         teamSetup t = (++) ammo $
-                eml ["eaddteam <hash> ", showB $ (1 + (readInt_ $ teamcolor t) :: Int) * 1234, " ", teamname t]
+                eml ["eaddteam <hash> ", showB $ (1 + (readInt_ $ teamcolor t) :: Int) * 2113696, " ", teamname t]
                 : em "erdriven"
                 : eml ["efort ", teamfort t]
-                : take (hhnum t) (
+                : take (2 * hhnum t) (
                     concatMap (\(HedgehogInfo hname hhat) -> [
                             eml ["eaddhh ", showB $ difficulty t, " ", initHealth, " ", hname]
                             , eml ["ehat ", hhat]
--- a/gameServer/HWProtoCore.hs	Mon Feb 25 19:48:35 2013 +0100
+++ b/gameServer/HWProtoCore.hs	Wed Feb 27 16:12:57 2013 +0100
@@ -30,12 +30,12 @@
 handleCmd ["PONG"] = do
     cl <- thisClient
     if pingsQueue cl == 0 then
-        return [ProtocolError "Protocol violation"]
+        return $ actionsPending cl ++ [ModifyClient (\c -> c{actionsPending = []})]
         else
         return [ModifyClient (\c -> c{pingsQueue = pingsQueue c - 1})]
 
-handleCmd ("CMD" : params) =
-    let c = concatMap B.words params in
+handleCmd ("CMD" : parameters) =
+    let c = concatMap B.words parameters in
         if not $ null c then
             h $ (upperCase . head $ c) : tail c
             else
@@ -45,6 +45,10 @@
         h ["STATS"] = handleCmd ["STATS"]
         h ["PART", msg] = handleCmd ["PART", msg]
         h ["QUIT", msg] = handleCmd ["QUIT", msg]
+        h ["GLOBAL", msg] = do
+            rnc <- liftM snd ask
+            let chans = map (sendChan . client rnc) $ allClients rnc
+            return [AnswerClients chans ["CHAT", "[global notice]", msg]]
         h c = return [Warning . B.concat . L.intersperse " " $ "Unknown cmd" : c]
 
 handleCmd cmd = do
--- a/gameServer/HWProtoInRoomState.hs	Mon Feb 25 19:48:35 2013 +0100
+++ b/gameServer/HWProtoInRoomState.hs	Wed Feb 27 16:12:57 2013 +0100
@@ -77,9 +77,12 @@
                 SendUpdateOnThisRoom,
                 ModifyClient (\c -> c{teamsInGame = teamsInGame c + 1, clientClan = Just teamColor}),
                 AnswerClients clChan ["TEAM_ACCEPTED", tName],
-                AnswerClients clChan ["HH_NUM", tName, showB $ hhnum newTeam],
                 AnswerClients othChans $ teamToNet $ newTeam,
-                AnswerClients roomChans ["TEAM_COLOR", tName, teamColor]
+                AnswerClients roomChans ["TEAM_COLOR", tName, teamColor],
+                ModifyClient $ \c -> c{actionsPending = actionsPending cl
+                    ++ [AnswerClients clChan ["HH_NUM", tName, showB $ hhnum newTeam]]
+                    },
+                AnswerClients [sendChan cl] ["PING"]
                 ]
         where
         canAddNumber rt = (48::Int) - (sum $ map hhnum rt)
@@ -226,7 +229,7 @@
         (legalMsgs, nonEmptyMsgs) = checkNetCmd msg
 
 
-handleCmd_inRoom ["ROUNDFINISHED", correctly] = do
+handleCmd_inRoom ["ROUNDFINISHED", _] = do
     cl <- thisClient
     rm <- thisRoom
     chans <- roomClientsChans
@@ -242,7 +245,7 @@
         else
         return [] -- don't accept this message twice
     where
-        isCorrect = correctly == "1"
+--        isCorrect = correctly == "1"
 
 -- compatibility with clients with protocol < 38
 handleCmd_inRoom ["ROUNDFINISHED"] =
--- a/gameServer/HWProtoLobbyState.hs	Mon Feb 25 19:48:35 2013 +0100
+++ b/gameServer/HWProtoLobbyState.hs	Wed Feb 27 16:12:57 2013 +0100
@@ -92,9 +92,12 @@
                 , AnswerClients [sendChan cl] $ ["CLIENT_FLAGS", "+h", ownerNick]
             ]
             ++ (if clientProto cl < 38 then map (readynessMessage cl) jRoomClients else [sendStateFlags cl jRoomClients])
-            ++ answerFullConfig cl (mapParams jRoom) (params jRoom)
-            ++ answerTeams cl jRoom
-            ++ watchRound cl jRoom chans
+            ++ [AnswerClients [sendChan cl] ["PING"]
+                , ModifyClient $ \c -> c{actionsPending = actionsPending cl
+                    ++ answerFullConfig cl (mapParams jRoom) (params jRoom)
+                    ++ answerTeams cl jRoom
+                    ++ watchRound cl jRoom chans}
+                ]
 
         where
         readynessMessage cl c = AnswerClients [sendChan cl] [if isReady c then "READY" else "NOT_READY", nick c]
--- a/gameServer/NetRoutines.hs	Mon Feb 25 19:48:35 2013 +0100
+++ b/gameServer/NetRoutines.hs	Wed Feb 27 16:12:57 2013 +0100
@@ -47,6 +47,7 @@
                     Nothing
                     Nothing
                     0
+                    []
                     )
 
         writeChan chan $ Accept newClient
--- a/gameServer/OfficialServer/checker.hs	Mon Feb 25 19:48:35 2013 +0100
+++ b/gameServer/OfficialServer/checker.hs	Wed Feb 27 16:12:57 2013 +0100
@@ -32,10 +32,22 @@
 serverAddress = "netserver.hedgewars.org"
 protocolNumber = "43"
 
+getLines :: Handle -> IO [String]
+getLines h = g
+    where
+        g = do
+            l <- liftM Just (hGetLine h) `Exception.catch` (\(_ :: Exception.IOException) -> return Nothing)
+            if isNothing l then
+                return []
+                else
+                do
+                lst <- g
+                return $ fromJust l : lst
+
 
 engineListener :: Chan Message -> Handle -> IO ()
 engineListener coreChan h = do
-    output <- liftM lines $ hGetContents h
+    output <- getLines h
     debugM "Engine" $ show output
     if isNothing $ L.find start output then
         writeChan coreChan $ CheckFailed "No stats msg"
--- a/hedgewars/GSHandlers.inc	Mon Feb 25 19:48:35 2013 +0100
+++ b/hedgewars/GSHandlers.inc	Wed Feb 27 16:12:57 2013 +0100
@@ -1783,7 +1783,7 @@
         Gear^.Y := Gear^.Y + Gear^.dY;
 
         if (not Gear^.dY.isNegative) and (Gear^.dY > _0_001) then
-            SetAllHHToActive;
+            SetAllHHToActive(false);
 
         if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then
             begin
@@ -2382,7 +2382,9 @@
 
         repeat
             CurrentTeam^.CurrHedgehog := Succ(CurrentTeam^.CurrHedgehog) mod (CurrentTeam^.HedgehogsNumber);
-        until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear^.Damage = 0);
+        until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and 
+              (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear^.Damage = 0) and 
+              (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen]=0);
 
         SwitchCurrentHedgehog(@CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]);
         AmmoMenuInvalidated:= true; 
@@ -2876,6 +2878,7 @@
 var 
     t: PGearArray;
     ox, oy: hwFloat;
+    tempColl: Word; 
 begin
     AllInactive := false;
 
@@ -2894,11 +2897,12 @@
             exit
         end
     end;
-
-    if GameTicks > Gear^.FlightTime then
+    tempColl:= Gear^.CollisionMask;
+    Gear^.CollisionMask:= $007F;
+    if (TestCollisionYWithGear(Gear, hwSign(Gear^.dY)) <> 0) or TestCollisionXWithGear(Gear, hwSign(Gear^.dX)) or (GameTicks > Gear^.FlightTime) then
         t := CheckGearsCollision(Gear)
-        
     else t := nil;
+    Gear^.CollisionMask:= tempColl;
     //fixes drill not exploding when touching HH bug
     
     if (Gear^.Timer = 0) or ((t <> nil) and (t^.Count <> 0))
@@ -5042,7 +5046,138 @@
 A frozen hog will animate differently.  To be decided, but possibly in a similar fashion to a grave when it comes to explosions.  The hog might (possibly) not be damaged by explosions.  This might make freezing potentially useful for friendlies in a bad position.  It might be better to allow damage though.
 A frozen hog stays frozen for a certain number of turns. Each turn the frozen overlay becomes fainter, until it fades and the hog animates normally again.
 *)
+
+
+procedure updateFuel(Gear: PGear);
+var 
+  t:LongInt;
+begin
+    t:= Gear^.Health div 10;
+    if (t <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
+    begin
+    Gear^.Damage:= t;
+    FreeTexture(Gear^.Tex);
+    Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(t) +
+              '%', cWhiteColor, fntSmall)
+    end;
+    if GameTicks mod 10 = 0 then dec(Gear^.Health);
+end;
+
+
+procedure updateTarget(Gear:PGear; newX, newY:HWFloat);
+    var
+    iter:PGear;    
+begin
+  with Gear^ do
+  begin
+    dX:= newX;
+    dY:= newY;
+    Pos:= 0;
+    Target.X:= NoPointX;
+    LastDamage:= nil;
+    X:= Hedgehog^.Gear^.X;
+    Y:= Hedgehog^.Gear^.Y;
+    //unfreeze all semifrozen hogs - make this generic hog cleanup
+(*
+    iter := GearsList;
+    while iter <> nil do
+        begin
+        if (iter^.Kind = gtHedgehog) and 
+        (iter^.Hedgehog^.Effects[heFrozen] and $FF = 0) then 
+        iter^.Hedgehog^.Effects[heFrozen]:= 0;
+        iter:= iter^.NextGear
+        end 
+*)
+  end;
+end;
+
+
+function isLandscapeEdge(weight:Longint):boolean;
+begin
+    result := (weight < 8) and (weight >= 2);
+end;
+
+function isLandscape(weight:Longint):boolean;
+begin
+    result := weight < 2;
+end;
+
+function isEmptySpace(weight:Longint):boolean;
+begin
+    result := not isLandscape(weight) and not isLandscapeEdge(weight);
+end;
+
+
+function getPixelWeight(x, y:Longint): Longint;
+var
+    i, j:Longint;
+begin    
+    result := 0;
+    for i := x - 1 to x + 1 do
+        for j := y - 1 to y + 1 do 
+        begin
+        if (i < 0) or 
+           (i > LAND_WIDTH - 1) or 
+           (j < 0) or 
+           (j > LAND_HEIGHT -1) or 
+           ((Land[j, i] and $FF00) = 0) then
+           begin
+           result := result + 1;
+           end;
+        end;
+end;
+
+
+procedure drawIcePixel(x, y:Longint);
+var 
+    iceSurface: PSDL_Surface;
+    icePixels: PLongwordArray;
+    pictureX, pictureY: LongInt;
+    w, c: LongWord;
+begin
+    if Land[y, x] and lfIce <> 0 then exit;
+// So. 3 parameters here. Ice colour, Ice opacity, and a bias on the greyscaled pixel towards lightness
+    iceSurface:= SpritesData[sprIceTexture].Surface;
+    pictureX := x mod iceSurface^.w;
+    pictureY := y mod iceSurface^.h;
+    icePixels := iceSurface^.pixels;
+    w:= LandPixels[y, x];
+    w:= round(((w shr RShift and $FF) * RGB_LUMINANCE_RED +
+          (w shr BShift and $FF) * RGB_LUMINANCE_GREEN +
+          (w shr GShift and $FF) * RGB_LUMINANCE_BLUE));
+    if w < 128 then w:= w+128;
+    if w > 255 then w:= 255;
+    w:= (w shl RShift) or (w shl BShift) or (w shl GShift) or (LandPixels[y,x] and AMask);
+    //LandPixels[y, x]:= w;
+    LandPixels[y, x]:= addBgColor(w, IceColor);
+    LandPixels[y, x]:= addBgColor(LandPixels[y, x], icePixels^[iceSurface^.w * (y mod iceSurface^.h) + (x mod iceSurface^.w)]);
+
+    Land[y, x] := Land[y, x] or lfIce;
+end;
+
+procedure DrawIce(x, y: Longint); 
+    const iceRadius :Longint = 32;
+var
+    i, j: Longint;
+    weight: Longint;
+    landRect : TSDL_RECT;
+begin
+    FillRoundInLandWithIce(x, y, iceRadius);
+    SetAllHHToActive; 
+    landRect.x := min(max(x - iceRadius, 0), LAND_WIDTH - 1);
+    landRect.y := min(max(y - iceRadius, 0), LAND_HEIGHT - 1);
+    landRect.w := min(2*iceRadius, LAND_WIDTH - landRect.x - 1);
+    landRect.h := min(2*iceRadius, LAND_HEIGHT - landRect.y - 1);
+    UpdateLandTexture(landRect.x, landRect.w, landRect.y, landRect.h, true);
+end;
+
+
 procedure doStepIceGun(Gear: PGear);
+const iceWaitCollision:Longint = 0;
+const iceCollideWithGround:Longint = 1;
+const iceWaitNextTarget:Longint = 2;
+const iceCollideWithHog:Longint = 4;
+const groundFreezingTime:Longint = 1000;
 var
     HHGear: PGear;
     ndX, ndY: hwFloat;
@@ -5050,7 +5185,7 @@
     hogs: PGearArrayS;
 begin
     HHGear := Gear^.Hedgehog^.Gear;
-    if (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) then
+    if (Gear^.Message and gmAttack <> 0) or (Gear^.Health = 0) or (HHGear = nil) or (HHGear^.Damage <> 0) then
         begin
         DeleteGear(Gear);
         AfterAttack;
@@ -5058,16 +5193,9 @@
         end
     else
         begin
-        t:= Gear^.Health div 10;
-        if (t <> Gear^.Damage) and ((GameTicks and $3F) = 0) then
-            begin
-            Gear^.Damage:= t;
-            FreeTexture(Gear^.Tex);
-            Gear^.Tex := RenderStringTex(trmsg[sidFuel] + ': ' + inttostr(t) +
-                         '%', cWhiteColor, fntSmall)
-            end
+        updateFuel(Gear);
         end;
-    if GameTicks mod 10 = 0 then dec(Gear^.Health);
+
     with Gear^ do
         begin
         HedgehogChAngle(HHGear);
@@ -5077,65 +5205,76 @@
            ((Target.X <> NoPointX) and (Target.X and LAND_WIDTH_MASK = 0) and 
              (Target.Y and LAND_HEIGHT_MASK = 0) and ((Land[Target.Y, Target.X] = 0))) then
             begin
-            dX:= ndX;
-            dY:= ndY;
-            Pos:= 0;
-            Target.X:= NoPointX;
-            LastDamage:= nil;
-            X:= HHGear^.X;
-            Y:= HHGear^.Y;
-(* unfreeze all semifrozen hogs - make this generic hog cleanup
-            iter := GearsList;
-            while iter <> nil do
-                begin
-                if (iter^.Kind = gtHedgehog) and 
-                   (iter^.Hedgehog^.Effects[heFrozen] < 0) then 
-                    iter^.Hedgehog^.Effects[heFrozen]:= 0;
-                iter:= iter^.NextGear
-                end *)
+                updateTarget(Gear, ndX, ndY);
+                IceState := iceWaitCollision;
             end
         else
             begin
             X:= X + dX;
             Y:= Y + dY;
             gX:= hwRound(X);
-            gY:= hwRound(Y);
-            if Target.X = NoPointX then t:= hwRound(hwSqr(X-HHGear^.X)+hwSqr(Y-HHGear^.Y));
+            gY:= hwRound(Y);    
+            if Target.X = NoPointX then 
+            begin
+                t:= hwRound(hwSqr(X-HHGear^.X)+hwSqr(Y-HHGear^.Y));
+            end;
+
             if Target.X <> NoPointX then
-                begin
+            begin
+                CheckCollisionWithLand(Gear);
+                if (State and gstCollision) <> 0 then
+                begin        
+                    if IceState = iceWaitCollision then
+                    begin
+                        IceState := iceCollideWithGround;
+                        IceTime := GameTicks;                    
+                    end;
+                end;
+
                 if (abs(gX-Target.X) < 2) and (abs(gY-Target.Y) < 2) then
-                    begin
+                begin
                     X:= HHGear^.X;
                     Y:= HHGear^.Y
-                    end;
+                end;
+
+                if (IceState = iceCollideWithGround) and ((GameTicks - IceTime) > groundFreezingTime) then
+                begin 
+                    DrawIce(Target.X, Target.Y);                                        
+                    IceState := iceWaitNextTarget;
+                end;
+
 // freeze nearby hogs
-                if GameTicks mod 10 = 0 then dec(Gear^.Health);
-                hogs := GearsNear(Gear^.X, Gear^.Y, gtHedgehog, Gear^.Radius);
+                hogs := GearsNear(int2hwFloat(Target.X), int2hwFloat(Target.Y), gtHedgehog, Gear^.Radius*2);
                 if hogs.size > 0 then
                     for i:= 0 to hogs.size - 1 do
                         if hogs.ar^[i] <> HHGear then
-                            begin
-                            //if Gear^.Hedgehog^.Effects[heFrozen]:= 0;
-                            end;
+                            if GameTicks mod 5 = 0 then 
+                                begin
+                                hogs.ar^[i]^.Active:= true;
+                                if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] < 256 then
+                                    hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] := hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] + 1
+                                else if hogs.ar^[i]^.Hedgehog^.Effects[heFrozen] = 256 then
+                                    hogs.ar^[i]^.Hedgehog^.Effects[heFrozen]:= 100000
+                                end;
                 inc(Pos)
-                end
+            end
             else if (t > 400) and ((gY > cWaterLine) or
                     (((gX and LAND_WIDTH_MASK = 0) and (gY and LAND_HEIGHT_MASK = 0))
                         and (Land[gY, gX] <> 0))) then
-                begin
+            begin
                 Target.X:= gX;
                 Target.Y:= gY;
                 X:= HHGear^.X;
                 Y:= HHGear^.Y
-                end;
-            if (gX > max(LAND_WIDTH,4096)*2) or
+            end;
+            {if (gX > max(LAND_WIDTH,4096)*2) or
                     (gX < -max(LAND_WIDTH,4096)) or
                     (gY < -max(LAND_HEIGHT,4096)) or
                     (gY > max(LAND_HEIGHT,4096)+512) then
-                begin
+            begin
                 X:= HHGear^.X;
                 Y:= HHGear^.Y
-                end
+            end}
         end
     end;
 end;
--- a/hedgewars/uChat.pas	Mon Feb 25 19:48:35 2013 +0100
+++ b/hedgewars/uChat.pas	Wed Feb 27 16:12:57 2013 +0100
@@ -394,9 +394,7 @@
         SetLine(InputStr, '', true)
     else
         begin
-        // err, does anyone have any documentation on this sequence?
-        // ^^ isn't it obvious? 27 is esc, 32 is space, inbetween is "/team"
-        KeyPressChat(27);
+        // "/team "
         KeyPressChat(47);
         KeyPressChat(116);
         KeyPressChat(101);
--- a/hedgewars/uCommandHandlers.pas	Mon Feb 25 19:48:35 2013 +0100
+++ b/hedgewars/uCommandHandlers.pas	Wed Feb 27 16:12:57 2013 +0100
@@ -594,7 +594,6 @@
             if bShowAmmoMenu then
                 bShowAmmoMenu:= false
             else if not(CurrentTeam^.Extdriven) and (((Gear^.State and (gstAttacking or gstAttacked)) <> 0)
-            or ((MultiShootAttacks > 0) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) = 0))
             or ((Gear^.State and gstHHDriven) = 0)) then
                 begin
                 end
--- a/hedgewars/uGears.pas	Mon Feb 25 19:48:35 2013 +0100
+++ b/hedgewars/uGears.pas	Wed Feb 27 16:12:57 2013 +0100
@@ -46,7 +46,8 @@
 procedure ProcessGears;
 procedure EndTurnCleanup;
 procedure SetAllToActive;
-procedure SetAllHHToActive;
+procedure SetAllHHToActive; inline;
+procedure SetAllHHToActive(Ice: boolean);
 procedure DrawGears;
 procedure FreeGearsList;
 procedure AddMiscGears;
@@ -442,7 +443,8 @@
 
 if TurnTimeLeft > 0 then
     if CurrentHedgehog^.Gear <> nil then
-        if ((CurrentHedgehog^.Gear^.State and gstAttacking) = 0) then
+        if ((CurrentHedgehog^.Gear^.State and gstAttacking) = 0) and 
+            not(isInMultiShoot and (CurrentHedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle])) then
                 begin
                 if (TurnTimeLeft = 5000)
                 and (cHedgehogTurnTime >= 10000)
@@ -561,7 +563,12 @@
     end
 end;
 
-procedure SetAllHHToActive;
+procedure SetAllHHToActive; inline;
+begin
+SetAllHHToActive(true)
+end;
+
+procedure SetAllHHToActive(Ice: boolean);
 var t: PGear;
 begin
 AllInactive:= false;
@@ -569,12 +576,14 @@
 while t <> nil do
     begin
     if (t^.Kind = gtHedgehog) or (t^.Kind = gtExplosives) then
-        t^.Active:= true;
+        begin
+        if (t^.Kind = gtHedgehog) and Ice then CheckIce(t);
+        t^.Active:= true
+        end;
     t:= t^.NextGear
     end
 end;
 
-
 procedure DrawGears;
 var Gear: PGear;
     x, y: LongInt;
@@ -765,6 +774,8 @@
     begin
     dec(i);
     Gear:= t^.ar[i];
+    if (Ammo^.Kind = gtFlame) and (Gear^.Kind = gtHedgehog) and (Gear^.Hedgehog^.Effects[heFrozen] > 255) then
+        Gear^.Hedgehog^.Effects[heFrozen]:= max(255,Gear^.Hedgehog^.Effects[heFrozen]-10000);
     tmpDmg:= ModifyDamage(Damage, Gear);
     if (Gear^.State and gstNoDamage) = 0 then
         begin
@@ -779,6 +790,7 @@
         if (Gear^.Kind = gtHedgehog) and (Ammo^.State and gsttmpFlag <> 0) and (Ammo^.Kind = gtShover) then
             Gear^.FlightTime:= 1;
 
+
         case Gear^.Kind of
             gtHedgehog,
             gtMine,
--- a/hedgewars/uGearsHedgehog.pas	Mon Feb 25 19:48:35 2013 +0100
+++ b/hedgewars/uGearsHedgehog.pas	Wed Feb 27 16:12:57 2013 +0100
@@ -29,6 +29,7 @@
 procedure HedgehogChAngle(HHGear: PGear); 
 procedure PickUp(HH, Gear: PGear);
 procedure AddPickup(HH: THedgehog; ammo: TAmmoType; cnt, X, Y: LongWord);
+procedure CheckIce(Gear: PGear); inline;
 
 implementation
 uses uConsts, uVariables, uFloat, uAmmos, uSound, uCaptions, 
@@ -53,7 +54,6 @@
     prevAmmo:= CurAmmoType;
     ammoidx:= 0;
     if ((HHGear^.State and (gstAttacking or gstAttacked)) <> 0)
-    or ((MultiShootAttacks > 0) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) = 0))
     or ((HHGear^.State and gstHHDriven) = 0) then
         exit;
     ChangeAmmo:= true;
@@ -61,8 +61,12 @@
     while (ammoidx < cMaxSlotAmmoIndex) and (Ammo^[slot, ammoidx].AmmoType <> CurAmmoType) do
         inc(ammoidx);
 
-    if ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) <> 0) and (MultiShootAttacks > 0) then
-        OnUsedAmmo(HHGear^.Hedgehog^);
+    if (MultiShootAttacks > 0) then
+        begin
+        if (CurAmmoType = amSniperRifle) and ((GameFlags and gfArtillery) = 0) then
+            cArtillery := false;
+        OnUsedAmmo(HHGear^.Hedgehog^)
+        end;
 
     MultiShootAttacks:= 0;
     HHGear^.Message:= HHGear^.Message and (not (gmLJump or gmHJump));
@@ -374,7 +378,10 @@
                                  end;
                     //amStructure: newGear:= AddGear(hwRound(lx) + hwSign(dX) * 7, hwRound(ly), gtStructure, gstWait, SignAs(_0_02, dX), _0, 3000);
                        amTardis: newGear:= AddGear(hwRound(X), hwRound(Y), gtTardis, 0, _0, _0, 5000);
-                       amIceGun: newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
+                       amIceGun: begin
+                       newGear:= AddGear(hwRound(X), hwRound(Y), gtIceGun, 0, _0, _0, 0);
+                       newGear^.radius := 8;
+                       end;
             end;
             if altUse and (newGear <> nil) then
                begin
@@ -455,7 +462,7 @@
             if (CurAmmoGear <> nil)
                 and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AltUse) = 0){check for dropping ammo from rope} then
                 begin
-                if CurAmmoType = amRope then Message:= Message or gmAttack;
+                if CurAmmoType in [amRope,amResurrector] then Message:= Message or gmAttack;
                 CurAmmoGear^.Message:= Message
                 end
             else
@@ -775,7 +782,7 @@
     if (not cArtillery) and ((Gear^.Message and gmPrecise) = 0) then
         MakeHedgehogsStep(Gear);
 
-    SetAllHHToActive;
+    SetAllHHToActive(false);
     AddGearCI(Gear)
     end
 end;
@@ -998,20 +1005,13 @@
     Hedgehog: PHedgehog;
 begin
 Hedgehog:= HHGear^.Hedgehog;
-// Some weapons, deagle in particular, wouldn't play so nice in infinite attack mode if hogs were still moving.  Most likely scenario
-// is trying to shoot them twice while rolling.  This is mostly about not wasting ammo, but shouldn't apply to gears not using AmmoShove (portal
-// Should we rethink AmmoShove? Presumably we'd need a way of knowing if current gear had already attacked a gear
-if isInMultiShoot and not AllInactive and (Hedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle]) then HHGear^.Message:= HHGear^.Message and not gmAttack;
-(*
-if isInMultiShoot then
-    HHGear^.Message:= 0;
-*)
-
-(*if ((Ammoz[CurrentHedgehog^.CurAmmoType].Ammo.Propz and ammoprop_Utility) <> 0) and isInMultiShoot then 
-    AllInactive:= true
-else if not isInMultiShoot then
-   AllInactive:= false;*)
- AllInactive:= false;
+//if isInMultiShoot and not AllInactive and (Hedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle]) then HHGear^.Message:= HHGear^.Message and not gmAttack;
+if isInMultiShoot and (Hedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle]) then
+    begin
+    AllInactive:= true;
+    HHGear^.Message:= 0
+    end
+else AllInactive:= false;
 
 if (TurnTimeLeft = 0) or (HHGear^.Damage > 0) then
     begin
@@ -1128,7 +1128,7 @@
     exit
     end;
 
-    if Hedgehog^.Gear <> nil then
+    if not(isInMultiShoot and (Hedgehog^.CurAmmoType in [amShotgun, amDEagle, amSniperRifle])) and (Hedgehog^.Gear <> nil) then
         begin
         if GHStepTicks > 0 then
             dec(GHStepTicks);
@@ -1200,7 +1200,7 @@
     if Gear^.Timer = 0 then
         begin
         Gear^.State:= Gear^.State and (not (gstWait or gstLoser or gstWinner or gstAttacked or gstNotKickable or gstHHChooseTarget));
-        Gear^.Active:= false;
+        if Gear^.Hedgehog^.Effects[heFrozen] = 0 then Gear^.Active:= false;
         AddGearCI(Gear);
         exit
         end
@@ -1210,40 +1210,24 @@
 AllInactive:= false
 end;
 
-////////////////////////////////////////////////////////////////////////////////
-procedure doStepHedgehog(Gear: PGear);
+procedure CheckIce(Gear: PGear); inline;
 (*
 var x,y,tx,ty: LongInt;
     tdX, tdY, slope: hwFloat; 
     land: Word; *)
 var slope: hwFloat; 
 begin
-CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel;
-if (Gear^.Message and gmDestroy) <> 0 then
-    begin
-    DeleteGear(Gear);
-    exit
-    end;
-
-if (Gear^.State and gstHHDriven) = 0 then
-    doStepHedgehogFree(Gear)
-else
-    begin
-    with Gear^.Hedgehog^ do
-        if Team^.hasGone then
-            TeamGoneEffect(Team^)
-        else
-            doStepHedgehogDriven(Gear)
-    end;
-if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0)
-and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0)
-and (not Gear^.dY.isNegative) and (GameTicks mod (100*LongWOrd(hwRound(cMaxWindSpeed*2/cGravity))) = 0)
-and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
-    begin
-    slope:= CalcSlopeBelowGear(Gear);
-    Gear^.dX:=Gear^.dX+slope*_0_07;
-    if slope.QWordValue <> 0 then
-        Gear^.State:= Gear^.State or gstMoving;
+    if (Gear^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0)
+    and (Gear^.State and (gstHHJumping or gstHHHJump or gstAttacking) = 0)
+    and (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) and lfIce <> 0) then
+        begin
+        slope:= CalcSlopeBelowGear(Gear);
+        if slope.QWordValue > 730144440 then // ignore mild slopes
+            begin
+            Gear^.dX:=Gear^.dX+slope*cGravity*_256;
+            Gear^.State:= Gear^.State or gstMoving
+            end
+        end;
 (*
     x:= hwRound(Gear^.X);
     y:= hwRound(Gear^.Y);
@@ -1258,7 +1242,35 @@
     AddVisualGear(x + hwRound(_40 * slope), y - hwRound(_40 * slope), vgtSmokeTrace);
     AddVisualGear(x - hwRound(_50 * slope), y + hwRound(_50 * slope), vgtSmokeTrace);
     AddVisualGear(x + hwRound(_50 * slope), y - hwRound(_50 * slope), vgtSmokeTrace); *)
-    end
+end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepHedgehog(Gear: PGear);
+begin
+CheckSum:= CheckSum xor Gear^.Hedgehog^.BotLevel;
+if (Gear^.Message and gmDestroy) <> 0 then
+    begin
+    DeleteGear(Gear);
+    exit
+    end;
+if GameTicks mod 100 = 0 then CheckIce(Gear);
+if Gear^.Hedgehog^.Effects[heFrozen] > 0 then 
+    begin
+    if Gear^.Hedgehog^.Effects[heFrozen] > 256 then
+        dec(Gear^.Hedgehog^.Effects[heFrozen])
+    else if GameTicks mod 10 = 0 then
+        dec(Gear^.Hedgehog^.Effects[heFrozen])
+    end;
+if (Gear^.State and gstHHDriven) = 0 then
+    doStepHedgehogFree(Gear)
+else
+    begin
+    with Gear^.Hedgehog^ do
+        if Team^.hasGone then
+            TeamGoneEffect(Team^)
+        else
+            doStepHedgehogDriven(Gear)
+    end;
 end;
 
 end.
--- a/hedgewars/uGearsRender.pas	Mon Feb 25 19:48:35 2013 +0100
+++ b/hedgewars/uGearsRender.pas	Wed Feb 27 16:12:57 2013 +0100
@@ -211,6 +211,8 @@
     defaultPos, HatVisible: boolean;
     HH: PHedgehog;
     CurWeapon: PAmmo;
+    iceOffset:Longint;
+    r:TSDL_Rect;
 begin
     HH:= Gear^.Hedgehog;
     if HH^.Unplaced then
@@ -239,6 +241,29 @@
     defaultPos:= true;
     HatVisible:= false;
 
+    if HH^.Effects[heFrozen] > 0 then
+        if HH^.Effects[heFrozen] < 256 then
+            begin
+            DrawHedgehog(sx, sy,
+                    sign,
+                    0,
+                    0,
+                    0);
+            defaultPos:= false;
+            HatVisible:= true
+            end
+        else 
+            begin
+            DrawHedgehog(sx, sy,
+                    sign,
+                    2,
+                    4,
+                    0);
+            defaultPos:= false;
+            HatVisible:= false;
+            exit
+            end;
+
 
     if HH^.Effects[hePoisoned] <> 0 then
         begin
@@ -247,6 +272,7 @@
         Tint($FF, $FF, $FF, $FF)
         end;
 
+
     if ((Gear^.State and gstWinner) <> 0) and
     ((CurAmmoGear = nil) or (CurAmmoGear^.Kind <> gtPickHammer)) then
         begin
@@ -538,7 +564,7 @@
                         DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex)
                     end;
                 gtIceGun:
-                    begin DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle);
+                    begin DrawSpriteRotated(sprIceGun, hx, hy, sign, aangle);
                     if CurAmmoGear^.Tex <> nil then
                         DrawTextureCentered(sx, sy - 40, CurAmmoGear^.Tex)
                     end;
@@ -669,7 +695,7 @@
                 amBee: DrawSpriteRotatedF(sprHandBee, hx, hy, (RealTicks div 125) mod 4, sign, aangle);
                 amFlamethrower: DrawSpriteRotatedF(sprHandFlamethrower, hx, hy, (RealTicks div 125) mod 4, sign, aangle);
                 amLandGun: DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle);
-                amIceGun: DrawSpriteRotated(sprHandBallgun, hx, hy, sign, aangle);
+                amIceGun: DrawSpriteRotated(sprIceGun, hx, hy, sign, aangle);
                 amResurrector: DrawCircle(ox, oy, 98, 4, $F5, $DB, $35, $AA); // I'd rather not like to hardcode 100 here
             end;
 
@@ -917,6 +943,23 @@
         Tint($FF, $FF, $FF, max($40, round($FF * abs(1 - ((RealTicks div 2 + Gear^.uid * 491) mod 1500) / 750))));
         DrawSprite(sprInvulnerable, sx - 24, sy - 24, 0);
         end;
+
+    if HH^.Effects[heFrozen] = HH^.Effects[heFrozen] and $FF then
+        begin
+       /// Tint($00, $FF, $40, $40);  (HH^.Effects[heFrozen] and $FF)
+        iceOffset:= trunc(HH^.Effects[heFrozen] / 256 * 64);
+        Tint($FF, $FF, $FF, $FF);        
+        r.x := 128;
+        r.y := 128 - iceOffset;
+        r.w := 64;
+        r.h := iceOffset;
+        //DrawTextureFromRect(sx-32, sy-iceoffset+32, @r, SpritesData[sprFrozenHog].texture);
+        DrawTextureFromRectDir(sx-16+sign*2, sy+48-iceoffset, r.w, r.h, @r, HHTexture, sign);
+
+        Tint($FF, $FF, $FF, $FF);
+        end;
+
+
     if cVampiric and
     (CurrentHedgehog^.Gear <> nil) and
     (CurrentHedgehog^.Gear = Gear) then
--- a/hedgewars/uGearsUtils.pas	Mon Feb 25 19:48:35 2013 +0100
+++ b/hedgewars/uGearsUtils.pas	Wed Feb 27 16:12:57 2013 +0100
@@ -182,6 +182,7 @@
 i:= _1;
 if (CurrentHedgehog <> nil) and CurrentHedgehog^.King then
     i:= _1_5;
+if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.Effects[heFrozen] > 0) then i:=i*_0_2;
 if (Gear^.Hedgehog <> nil) and (Gear^.Hedgehog^.King) then
     ModifyDamage:= hwRound(_0_01 * cDamageModifier * dmg * i * cDamagePercent * _0_5)
 else
--- a/hedgewars/uIO.pas	Mon Feb 25 19:48:35 2013 +0100
+++ b/hedgewars/uIO.pas	Wed Feb 27 16:12:57 2013 +0100
@@ -249,7 +249,10 @@
             flushBuffer();
             
         Move(s, sendBuffer.buf[sendBuffer.count], byte(s[0]) + 1);
-        inc(sendBuffer.count, byte(s[0]) + 1)
+        inc(sendBuffer.count, byte(s[0]) + 1);
+        
+        if (s[1] = 'N') or (s[1] = '#') then
+            flushBuffer();
         end else
         SDLNet_TCP_Send(IPCSock, @s, Succ(byte(s[0])))
     end
--- a/hedgewars/uLandGraphics.pas	Mon Feb 25 19:48:35 2013 +0100
+++ b/hedgewars/uLandGraphics.pas	Wed Feb 27 16:12:57 2013 +0100
@@ -36,6 +36,7 @@
 procedure DrawHLinesExplosions(ar: PRangeArray; Radius: LongInt; y, dY: LongInt; Count: Byte);
 procedure DrawTunnel(X, Y, dX, dY: hwFloat; ticks, HalfWidth: LongInt);
 procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword);
+procedure FillRoundInLandWithIce(X, Y, Radius: LongInt);
 procedure ChangeRoundInLand(X, Y, Radius: LongInt; doSet, isCurrent: boolean);
 function  LandBackPixel(x, y: LongInt): LongWord;
 procedure DrawLine(X1, Y1, X2, Y2: LongInt; Color: Longword);
@@ -158,6 +159,8 @@
     end
 end;
 
+
+
 procedure FillRoundInLand(X, Y, Radius: LongInt; Value: Longword);
 var dx, dy, d: LongInt;
 begin
@@ -243,6 +246,130 @@
 
 end;
 
+
+function isLandscapeEdge(weight:Longint):boolean;
+begin
+    result := (weight < 8) and (weight >= 2);
+end;
+
+function isLandscape(weight:Longint):boolean;
+begin
+    result := weight < 2;
+end;
+
+function isEmptySpace(weight:Longint):boolean;
+begin
+    result := not isLandscape(weight) and not isLandscapeEdge(weight);
+end;
+
+function getPixelWeight(x, y:Longint): Longint;
+var
+    i, j:Longint;
+begin
+    result := 0;
+    for i := x - 1 to x + 1 do
+        for j := y - 1 to y + 1 do
+        begin
+        if (i < 0) or
+           (i > LAND_WIDTH - 1) or
+           (j < 0) or
+           (j > LAND_HEIGHT -1) or
+           ((Land[j, i] and $FF00) = 0) then
+           begin
+           result := result + 1;
+           end;
+        end;
+end;
+
+procedure drawIcePixel(y, x:Longint);
+var
+    iceSurface: PSDL_Surface;
+    icePixels: PLongwordArray;
+    pictureX, pictureY: LongInt;
+    w, c: LongWord;
+    weight: Longint;
+begin
+    weight := getPixelWeight(x, y);
+    if isLandscape(weight) then
+        begin
+        // So. 3 parameters here. Ice colour, Ice opacity, and a bias on the greyscaled pixel towards lightness
+        iceSurface:= SpritesData[sprIceTexture].Surface;
+        pictureX := x mod iceSurface^.w;
+        pictureY := y mod iceSurface^.h;
+        icePixels := iceSurface^.pixels;
+        w:= LandPixels[y, x];
+        w:= round(((w shr RShift and $FF) * RGB_LUMINANCE_RED +
+              (w shr BShift and $FF) * RGB_LUMINANCE_GREEN +
+              (w shr GShift and $FF) * RGB_LUMINANCE_BLUE));
+        if w < 128 then w:= w+128;
+        if w > 255 then w:= 255;
+        w:= (w shl RShift) or (w shl BShift) or (w shl GShift) or (LandPixels[y,x] and AMask);
+        //LandPixels[y, x]:= w;
+        LandPixels[y, x]:= addBgColor(w, IceColor);
+        LandPixels[y, x]:= addBgColor(LandPixels[y, x], icePixels^[iceSurface^.w * (y mod iceSurface^.h) + (x mod iceSurface^.w)]);
+        Land[y, x] := land[y, x] or lfIce;
+        end
+    else if (isLandscapeEdge(weight)) then
+        begin
+        LandPixels[y, x] := $FFB2AF8A;
+        if Land[y, x] > 255 then Land[y, x] := Land[y, x] or lfIce;
+        end;
+
+end;
+
+function getIncrementInquarter(dx, dy, quarter: Longint): Longint;
+const directionX : array [0..3] of Longint = (0, 0, 1, -1);
+const directionY : array [0..3] of Longint = (1, -1, 0, 0);
+begin
+    getIncrementInquarter := directionX[quarter] * dx + directionY[quarter] * dy;
+end;
+
+function getIncrementInquarter2(dx, dy, quarter: Longint): Longint;
+const directionY : array [0..3] of Longint = (0, 0, 1, 1);
+const directionX : array [0..3] of Longint = (1, 1, 0, 0);
+begin
+    getIncrementInquarter2 := directionX[quarter] * dx + directionY[quarter] * dy;
+end;
+
+procedure FillLandCircleLinesIce(x, y, dx, dy: LongInt);
+var q, i, t: LongInt;
+begin
+for q := 0 to 3 do
+    begin
+        t:= y + getIncrementInquarter(dx, dy, q);
+        if (t and LAND_HEIGHT_MASK) = 0 then
+            for i:= Max(x - getIncrementInquarter2(dx, dy, q), 0) to Min(x + getIncrementInquarter2(dx, dy, q), LAND_WIDTH - 1) do
+                if (Land[t, i] and (lfIndestructible or lfIce) = 0) and (not disableLandBack or (Land[t, i] > 255))  then
+                    if (cReducedQuality and rqBlurryLand) = 0 then
+                       drawIcePixel(t, i)
+                    else
+                       drawIcePixel(t div 2, i div 2) ;
+    end;
+end;
+
+procedure FillRoundInLandWithIce(X, Y, Radius: LongInt);
+var dx, dy, d: LongInt;
+begin
+dx:= 0;
+dy:= Radius;
+d:= 3 - 2 * Radius;
+    while (dx < dy) do
+        begin
+        FillLandCircleLinesIce(x, y, dx, dy);
+        if (d < 0) then
+            d:= d + 4 * dx + 6
+        else
+            begin
+            d:= d + 4 * (dx - dy) + 10;
+            dec(dy)
+            end;
+        inc(dx)
+        end;
+    if (dx = dy) then
+        FillLandCircleLinesIce(x, y, dx, dy);
+end;
+
+
 function FillLandCircleLinesBG(x, y, dx, dy: LongInt): Longword;
 var i, t, by, bx: LongInt;
     cnt: Longword;
@@ -350,7 +477,7 @@
             else
                 LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
 
-            Land[t, i]:= Land[t, i] or lfDamaged;
+            Land[t, i]:= (Land[t, i] or lfDamaged) and not lfIce;
             //Despeckle(i, t);
             LandDirty[t div 32, i div 32]:= 1;
             end;
@@ -364,7 +491,7 @@
                 LandPixels[t, i]:= ExplosionBorderColor
             else
                 LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
-            Land[t, i]:= Land[t, i] or lfDamaged;
+            Land[t, i]:= (Land[t, i] or lfDamaged) and not lfIce;
             //Despeckle(i, t);
             LandDirty[t div 32, i div 32]:= 1;
             end;
@@ -379,7 +506,7 @@
             else
                LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
 
-            Land[t, i]:= Land[t, i] or lfDamaged;
+            Land[t, i]:= (Land[t, i] or lfDamaged) and not lfIce;
             //Despeckle(i, t);
             LandDirty[t div 32, i div 32]:= 1;
             end;
@@ -394,7 +521,7 @@
             else
                 LandPixels[t div 2, i div 2]:= ExplosionBorderColor;
 
-            Land[t, i]:= Land[t, i] or lfDamaged;
+            Land[t, i]:= (Land[t, i] or lfDamaged) and not lfIce;
             //Despeckle(i, y - dy);
             LandDirty[t div 32, i div 32]:= 1;
             end;
@@ -525,7 +652,7 @@
                 else
                     LandPixels[ty div 2, tx div 2]:= ExplosionBorderColor;
 
-                Land[ty, tx]:= Land[ty, tx] or lfDamaged;
+                Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and not lfIce;
                 LandDirty[ty div 32, tx div 32]:= 1;
                 end;
     inc(y, dY)
@@ -567,6 +694,7 @@
     and ((tx and LAND_WIDTH_MASK) = 0)
     and (((Land[ty, tx] and lfBasic) <> 0) or ((Land[ty, tx] and lfObject) <> 0)) then
         begin
+        Land[ty, tx]:= Land[ty, tx] and not lfIce;
         if despeckle then
             begin
             Land[ty, tx]:= Land[ty, tx] or lfDamaged;
@@ -595,7 +723,7 @@
         if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
         or ((Land[ty, tx] and lfObject) <> 0)) then
             begin
-            Land[ty, tx]:= Land[ty, tx] or lfDamaged;
+            Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and not lfIce;
             if despeckle then
                 LandDirty[ty div 32, tx div 32]:= 1;
             if (cReducedQuality and rqBlurryLand) = 0 then
@@ -638,7 +766,7 @@
     if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
     or ((Land[ty, tx] and lfObject) <> 0)) then
         begin
-        Land[ty, tx]:= Land[ty, tx] or lfDamaged;
+        Land[ty, tx]:=( Land[ty, tx] or lfDamaged) and not lfIce;
         if despeckle then
             LandDirty[ty div 32, tx div 32]:= 1;
         if (cReducedQuality and rqBlurryLand) = 0 then
@@ -664,7 +792,7 @@
     if ((ty and LAND_HEIGHT_MASK) = 0) and ((tx and LAND_WIDTH_MASK) = 0) and (((Land[ty, tx] and lfBasic) <> 0)
     or ((Land[ty, tx] and lfObject) <> 0)) then
         begin
-        Land[ty, tx]:= Land[ty, tx] or lfDamaged;
+        Land[ty, tx]:= (Land[ty, tx] or lfDamaged) and not lfIce;
         if despeckle then
             LandDirty[ty div 32, tx div 32]:= 1;
         if (cReducedQuality and rqBlurryLand) = 0 then
--- a/hedgewars/uRender.pas	Mon Feb 25 19:48:35 2013 +0100
+++ b/hedgewars/uRender.pas	Wed Feb 27 16:12:57 2013 +0100
@@ -26,15 +26,16 @@
 
 procedure DrawSprite            (Sprite: TSprite; X, Y, Frame: LongInt);
 procedure DrawSprite            (Sprite: TSprite; X, Y, FrameX, FrameY: LongInt);
-procedure DrawSpriteFromRect    (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt);
+procedure DrawSpriteFromRect    (Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline;
 procedure DrawSpriteClipped     (Sprite: TSprite; X, Y, TopY, RightX, BottomY, LeftX: LongInt);
 procedure DrawSpriteRotated     (Sprite: TSprite; X, Y, Dir: LongInt; Angle: real);
 procedure DrawSpriteRotatedF    (Sprite: TSprite; X, Y, Frame, Dir: LongInt; Angle: real);
 
 procedure DrawTexture           (X, Y: LongInt; Texture: PTexture); inline;
 procedure DrawTexture           (X, Y: LongInt; Texture: PTexture; Scale: GLfloat);
-procedure DrawTextureFromRect   (X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
-procedure DrawTextureFromRect   (X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
+procedure DrawTextureFromRect   (X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
+procedure DrawTextureFromRect   (X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
+procedure DrawTextureFromRectDir(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture; Dir: LongInt);
 procedure DrawTextureCentered   (X, Top: LongInt; Source: PTexture);
 procedure DrawTextureF          (Texture: PTexture; Scale: GLfloat; X, Y, Frame, Dir, w, h: LongInt);
 procedure DrawTextureRotated    (Texture: PTexture; hw, hh, X, Y, Dir: LongInt; Angle: real);
@@ -63,19 +64,23 @@
 
 var LastTint: LongWord = 0;
 
-procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt);
+procedure DrawSpriteFromRect(Sprite: TSprite; r: TSDL_Rect; X, Y, Height, Position: LongInt); inline;
 begin
 r.y:= r.y + Height * Position;
 r.h:= Height;
 DrawTextureFromRect(X, Y, @r, SpritesData[Sprite].Texture)
 end;
 
-procedure DrawTextureFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
+procedure DrawTextureFromRect(X, Y: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
 begin
-DrawTextureFromRect(X, Y, r^.w, r^.h, r, SourceTexture)
+DrawTextureFromRectDir(X, Y, r^.w, r^.h, r, SourceTexture, 1)
+end;
+procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture); inline;
+begin
+DrawTextureFromRectDir(X, Y, W, H, r, SourceTexture, 1)
 end;
 
-procedure DrawTextureFromRect(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture);
+procedure DrawTextureFromRectDir(X, Y, W, H: LongInt; r: PSDL_Rect; SourceTexture: PTexture; Dir: LongInt);
 var rr: TSDL_Rect;
     _l, _r, _t, _b: real;
     VertexBuffer, TextureBuffer: array [0..3] of TVertex2f;
@@ -101,14 +106,28 @@
 
 glBindTexture(GL_TEXTURE_2D, SourceTexture^.id);
 
-VertexBuffer[0].X:= X;
-VertexBuffer[0].Y:= Y;
-VertexBuffer[1].X:= rr.w + X;
-VertexBuffer[1].Y:= Y;
-VertexBuffer[2].X:= rr.w + X;
-VertexBuffer[2].Y:= rr.h + Y;
-VertexBuffer[3].X:= X;
-VertexBuffer[3].Y:= rr.h + Y;
+if Dir < 0 then
+    begin
+    VertexBuffer[0].X:= X + rr.w/2;
+    VertexBuffer[0].Y:= Y;
+    VertexBuffer[1].X:= X - rr.w/2;
+    VertexBuffer[1].Y:= Y;
+    VertexBuffer[2].X:= X - rr.w/2;
+    VertexBuffer[2].Y:= rr.h + Y;
+    VertexBuffer[3].X:= X + rr.w/2;
+    VertexBuffer[3].Y:= rr.h + Y;
+    end
+else
+    begin
+    VertexBuffer[0].X:= X;
+    VertexBuffer[0].Y:= Y;
+    VertexBuffer[1].X:= rr.w + X;
+    VertexBuffer[1].Y:= Y;
+    VertexBuffer[2].X:= rr.w + X;
+    VertexBuffer[2].Y:= rr.h + Y;
+    VertexBuffer[3].X:= X;
+    VertexBuffer[3].Y:= rr.h + Y;
+    end;
 
 TextureBuffer[0].X:= _l;
 TextureBuffer[0].Y:= _t;
--- a/hedgewars/uTeams.pas	Mon Feb 25 19:48:35 2013 +0100
+++ b/hedgewars/uTeams.pas	Wed Feb 27 16:12:57 2013 +0100
@@ -188,11 +188,11 @@
                 PrevHH:= CurrHedgehog mod HedgehogsNumber; // prevent infinite loop when CurrHedgehog = 7, but HedgehogsNumber < 8 (team is destroyed before its first turn)
                 repeat
                     CurrHedgehog:= Succ(CurrHedgehog) mod HedgehogsNumber;
-                until (Hedgehogs[CurrHedgehog].Gear <> nil) or (CurrHedgehog = PrevHH)
+                until ((Hedgehogs[CurrHedgehog].Gear <> nil) and (Hedgehogs[CurrHedgehog].Effects[heFrozen] = 0)) or (CurrHedgehog = PrevHH)
                 end
         until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) or (PrevTeam = CurrTeam) or ((CurrTeam = TagTeamIndex) and ((GameFlags and gfTagTeam) <> 0));
         end
-until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil);
+until (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear <> nil) and (CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Effects[heFrozen] = 0);
 
 SwitchCurrentHedgehog(@(CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog]));
 {$IFDEF USE_TOUCH_INTERFACE}
--- a/hedgewars/uTypes.pas	Mon Feb 25 19:48:35 2013 +0100
+++ b/hedgewars/uTypes.pas	Wed Feb 27 16:12:57 2013 +0100
@@ -86,7 +86,7 @@
             sprHandResurrector, sprCross, sprAirDrill, sprNapalmBomb,
             sprBulletHit, sprSnowball, sprHandSnowball, sprSnow,
             sprSDFlake, sprSDWater, sprSDCloud, sprSDSplash, sprSDDroplet, sprTardis,
-            sprSlider, sprBotlevels, sprHandKnife, sprKnife, sprStar
+            sprSlider, sprBotlevels, sprHandKnife, sprKnife, sprStar, sprIceTexture, sprIceGun, sprFrozenHog
             );
 
     // Gears that interact with other Gears and/or Land
@@ -259,6 +259,8 @@
             SoundChannel: LongInt;
             PortalCounter: LongWord;  // Hopefully temporary, but avoids infinite portal loops in a guaranteed fashion.
             AIHints: LongWord; // hints for ai. haha ^^^^^^ temporary, sure
+            IceTime: Longint; //time of ice beam with object some interaction  temporary
+            IceState: Longint; //state of ice gun temporary
             LastDamage: PHedgehog;
             end;
     TPGearArray = array of PGear;
--- a/hedgewars/uUtils.pas	Mon Feb 25 19:48:35 2013 +0100
+++ b/hedgewars/uUtils.pas	Wed Feb 27 16:12:57 2013 +0100
@@ -361,14 +361,14 @@
     if (#$1100  <= u) and  (
                            (u <= #$11FF )  or // Hangul Jamo
        ((#$2E80  <= u) and (u <= #$2FDF))  or // CJK Radicals Supplement / Kangxi Radicals
-       ((#$2FF0  <= u) and (u <= #$303F))  or // Ideographic Description Characters / CJK Radicals Supplement
-       ((#$3130  <= u) and (u <= #$318F))  or // Hangul Compatibility Jamo
+       ((#$2FF0  <= u) and (u <= #$31FF))  or // Ideographic Description Characters / CJK Radicals Supplement / Hiragana / Hangul Compatibility Jamo / Katakana
        ((#$31C0  <= u) and (u <= #$31EF))  or // CJK Strokes
-       ((#$3200  <= u) and (u <= #$4DBF))  or // Enclosed CJK Letters and Months / CJK Compatibility / CJK Unified Ideographs Extension A
+       ((#$3200  <= u) and (u <= #$4DBF))  or // Enclosed CJK Letters and Months / CJK Compatibility / CJK Unified Ideographs Extension A / Circled Katakana
        ((#$4E00  <= u) and (u <= #$9FFF))  or // CJK Unified Ideographs
        ((#$AC00  <= u) and (u <= #$D7AF))  or // Hangul Syllables
        ((#$F900  <= u) and (u <= #$FAFF))  or // CJK Compatibility Ideographs
-       ((#$FE30  <= u) and (u <= #$FE4F)))    // CJK Compatibility Forms
+       ((#$FE30  <= u) and (u <= #$FE4F))  or // CJK Compatibility Forms
+       ((#$FF66  <= u) and (u <= #$FF9D)))    // halfwidth katakana
        then 
         begin
             CheckCJKFont:=  THWFont( ord(font) + ((ord(High(THWFont))+1) div 2) );
--- a/hedgewars/uVariables.pas	Mon Feb 25 19:48:35 2013 +0100
+++ b/hedgewars/uVariables.pas	Wed Feb 27 16:12:57 2013 +0100
@@ -115,6 +115,7 @@
 
     // originally typed consts
     ExplosionBorderColor: LongWord;
+    IceColor            : LongWord;
     WaterOpacity: byte;
     SDWaterOpacity: byte;
     GrayScale: Boolean;
@@ -654,16 +655,18 @@
             Width: 3; Height: 17; imageWidth: 3; imageHeight: 17; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprSlider
             (FileName:  'botlevels'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
             Width: 22; Height: 15; imageWidth: 22; imageHeight: 15; saveSurf: true; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprBotlevels
-         (*   (FileName:  'amKnife'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
-            Width:  64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprHandKnife*)
             (FileName:  'amCleaver'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
             Width:  64; Height: 64; imageWidth: 64; imageHeight: 64; saveSurf: false; priority: tpMedium; getDimensions: false; getImageDimensions: false),// sprHandKnife
-            (*(FileName:  'knife'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
-            Width: 29; Height: 14; imageWidth: 64; imageHeight: 64; saveSurf: true; priority: tpLow; getDimensions: false; getImageDimensions: false) // sprKnife*)
             (FileName:  'cleaver'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
             Width: 64; Height: 64; imageWidth: 64; imageHeight: 128; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprKnife
             (FileName:  'star'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
-            Width: 12; Height: 12; imageWidth: 12; imageHeight: 12; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false) // sprStar
+            Width: 12; Height: 12; imageWidth: 12; imageHeight: 12; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprStar
+            (FileName:  'icetexture'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width: 128; Height: 128; imageWidth: 128; imageHeight: 128; saveSurf: true; priority: tpLow; getDimensions: false; getImageDimensions: true), // sprIceTexture
+            (FileName:  'amIceGun'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width: 32; Height: 32; imageWidth: 32; imageHeight: 32; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprIceGun
+            (FileName:  'amFrozenHog'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width: 64; Height: 64; imageWidth: 64; imageHeight: 64; saveSurf: false; priority: tpLow; getDimensions: false; getImageDimensions: false) // sprFrozenHog
             );
 
 const
@@ -2407,6 +2410,7 @@
     SDWaterOpacity:= $80;
     SDTint:= $80;
     ExplosionBorderColor:= $FF808080;
+    IceColor:= ($44 shl RShift) or ($97 shl GShift) or ($A9 shl BShift) or ($A0 shl AShift);
     WaterOpacity:= $80;
 
     cDrownSpeed.QWordValue  := 257698038;       // 0.06
Binary file share/hedgewars/Data/Graphics/Hedgehog.png has changed
Binary file share/hedgewars/Data/Graphics/Hedgehog/amFrozenHog.png has changed
Binary file share/hedgewars/Data/Graphics/Hedgehog/amIceGun.png has changed
Binary file share/hedgewars/Data/Graphics/icetexture.png has changed
--- a/share/hedgewars/Data/Locale/ja.txt	Mon Feb 25 19:48:35 2013 +0100
+++ b/share/hedgewars/Data/Locale/ja.txt	Wed Feb 27 16:12:57 2013 +0100
@@ -470,62 +470,62 @@
 03:55=ユーティリティ
 
 ; Weapon Descriptions (use | as line breaks)
-04:00=シンプルな手榴弾を使って敵を攻撃。そのタイマーがゼロに達するとそれが爆発する。1-5:セットグレネードのタイマー攻撃:より多くの電力をスローするようにホールド
-04:01=クラスター爆弾を使用して敵を攻撃。そのタイマーがゼロに達すると、それは小さな爆弾に分割されます。1-5:セットグレネードのタイマー攻撃:より多くの電力をスローするようにホールド
-04:02=風に影響されるかもしれない弾道発射体を使用して敵を攻撃。攻撃:より多くの電力を使って撮影するホールド
-04:03=選択したターゲットにロックされ爆発的な蜂を起動します。その精度を向上させるためにフルパワーを使って撮影しないでください。カーソル:ピックターゲット攻撃:より多くの電力を使って撮影するホールド
-04:04=2ショットでショットガンを使って敵を攻撃する。その広がりあなたのおかげで、あなたの対戦相手に危害を直接ヒットする必要はありません。攻撃:シュート(複数回)
-04:05=地下に移動!地面に穴を開けると他の領域に到達するを使用しています。攻撃の開始または停止掘り
-04:06=退屈?攻撃する方法はありません?あなたの弾薬を保存しますか?問題ありません!ちょうどあなたのターン、臆病者をスキップして!攻撃:戦闘せずにターンをスキップ
-04:07=ロープでタイムアウトショットを使用して、巨大な距離を埋める。他の豚またはドロップ手榴弾およびそれらの他の武器にスライドするように勢いを使用しています。攻撃:ドロップ手榴弾または類似の武器:ロープロングジャンプシュートまたは解放
-04:08=狭い通路の右またはそれらの足の下鉱山をドロップすることで、離れてあなたの敵を保つ。あなた自身でそれをトリガする前に撤退してください!攻撃:あなたの足の隣に地雷を削除します。
-04:09=あなたの照準が分からない?4打差までを使用して攻撃するためにデザートイーグルを使用しています。攻撃:シュート(複数回)
-04:10=ブルートフォースは常にオプションです。あなたの敵と後退の隣にあるこの古典的な爆発物をドロップします。攻撃:あなたの足の隣にあるドロップダイナマイト
-04:11=マップの国境を越えてまたは水の中にそれらをバッティングして敵の豚を取り除く。またはどのようにお友達にいくつかの鉱山をノックでしょうか?攻撃:あなたの前にバットすべてを
-04:12=このほとんど致命的な武道技術の力を解き放つに近いと個人的な取得します。攻撃:素晴らしいを実行します。
+04:00=シンプルな手榴弾を使って敵を攻撃。|そのタイマーがゼロに達するとそれが爆発する。|1-5:セットグレネードのタイマー攻撃:より多くの電力をスローするようにホールド
+04:01=クラスター爆弾を使用して敵を攻撃。|そのタイマーがゼロに達すると、それは小さな爆弾に分割されます。|1-5:セットグレネードのタイマー攻撃:より多くの電力をスローするようにホールド
+04:02=風に影響されるかもしれない弾道発射体を使用して敵を攻撃。|攻撃:より多くの電力を使って撮影するホールド
+04:03=選択したターゲットにロックされ爆発的な蜂を起動します。|その精度を向上させるためにフルパワーを使って撮影しないでください。|カーソル:ピックターゲット攻撃:より多くの電力を使って撮影するホールド
+04:04=2ショットでショットガンを使って敵を攻撃する。|その広がりあなたのおかげで、あなたの対戦相手に危害を直接ヒットする必要はありません。|攻撃:シュート(複数回)
+04:05=地下に移動!|地面に穴を開けると他の領域に到達するを使用しています。|攻撃の開始または停止掘り
+04:06=退屈?攻撃する方法はありません?あなたの弾薬を保存しますか?問題ありません!|ちょうどあなたのターン、臆病者をスキップして!|攻撃:戦闘せずにターンをスキップ
+04:07=ロープでタイムアウトショットを使用して、巨大な距離を埋める。|他の豚またはドロップ手榴弾およびそれらの他の武器にスライドするように勢いを使用しています。|攻撃:ドロップ手榴弾または類似の武器:ロープロングジャンプシュートまたは解放
+04:08=狭い通路の右またはそれらの足の下鉱山をドロップすることで、離れてあなたの敵を保つ。|あなた自身でそれをトリガする前に撤退してください!|攻撃:あなたの足の隣に地雷を削除します。
+04:09=あなたの照準が分からない?4打差までを使用して攻撃するためにデザートイーグルを使用しています。|攻撃:シュート(複数回)
+04:10=ブルートフォースは常にオプションです。|あなたの敵と後退の隣にあるこの古典的な爆発物をドロップします。|攻撃:あなたの足の隣にあるドロップダイナマイト
+04:11=マップの国境を越えてまたは水の中にそれらをバッティングして敵の豚を取り除く。|またはどのようにお友達にいくつかの鉱山をノックでしょうか?攻撃:あなたの前にバットすべてを
+04:12=このほとんど致命的な武道技術の力を解き放つに近いと個人的な取得します。|攻撃:素晴らしいを実行します。
 04:13=UNUSED
-04:14=高所恐怖症?優れたパラシュートをつかむ。それはあなたが遠すぎたら落ちる展開と秋のダメージを受けてから豚を保存します。攻撃:ドロップ手榴弾または類似の武器:パラシュートロングジャンプを伸ばし
-04:15=爆撃の実行を使用して敵を攻撃する飛行機の中で呼び出します。左右:選択してターゲット領域:攻撃方向のカーソルを決定
-04:16=ターゲットエリアにいくつかの鉱山をドロップするには飛行機の中で呼び出します。左右:選択してターゲット領域:攻撃方向のカーソルを決定
-04:17=避難が必要ですか?あなたがカバー付与固体地面にトンネルを掘るためにブロートーチを使用しています。攻撃の開始または停止掘り
-04:18=追加の保護が必要な場合、または地面を通過したいですか?好きなように、いくつかの桁に置きます。有効な位置に配置桁:左右:カーソルを配置する選択桁
-04:19=それはあなたが数秒以内に危険な状況から豚を保存することができますように、右瞬間テレポーテーションで使用するほぼすべての武器をより強力にすることができます。カーソル:選択してターゲット領域
-04:20=別の豚と、現在のターンを再生することができます。攻撃:スイッチング豚を有効にする
-04:21=インパクト時に複数の爆弾を解放します手榴弾のような弾丸を撃つ。攻撃:フルパワーで撃つ
-04:22=だけでなく、インディジョーンズのために!鞭は多くの状況で有用な武器である。あなたが崖から誰かを突き出すしたい場合は特に。攻撃:あなたの前にストライクのすべて
-04:23=あなたが失うものは何もない場合、これはかなり便利かもしれません。彼の方法上のすべてを傷つけると終了時に爆発し、特定の方向に彼を起動することで、豚を生け贄に捧げる。攻撃:壊滅的な、致命的な攻撃を開始
-04:24=誕生日おめでとう!このケーキを起動し、それが右の敵の隣に歩いて、彼らが爆発的パーティを持たせてみましょう。ケーキは、ほぼすべての地形を通過することができますが、彼は以前、この方法を爆発させるかもしれません。攻撃:ケーキを起動するか、停止させると爆発する
-04:25=(そして、いくつかのギャップや穴)が豚に向かってジャンプすることがあなたの敵を取得するには、この変装キットを使用しています。攻撃:キットを使用して、別の豚を誘惑しよう
-04:26=あなたの敵で、このジューシーなスイカをスローします。タイマーの期限が切れると、それはいくつかの爆発的な断片に分割されます。1-5:セットスイカのタイマー攻撃:より多くの電力を使って撮影するホールド
-04:27=この悪魔のよう爆発を使用して、あなたの対戦相手に業火の雨してみましょう。近すぎる小さな火災が長く続くかもしれないと爆発に得ることはありません。攻撃:より多くの電力を使って撮影するホールド
-04:28=このロケットを打ち上げた後の短い時間、それは固体地面を掘削を開始し、そのヒューズがトリガされると爆発するか、再び再浮上します。攻撃:より多くの電力を使って撮影するホールド
-04:29=これは小さな子供のためのものではありません!ボール銃は爆薬を充填した小さな色のボールのトンを発生させます。攻撃:アップダウン、フルパワーでシュートを目指して進みます
-04:30=強力なナパームストライキを起動するには飛行機の中で呼び出します。適切にこの攻撃を目指してそこに座って不運な豚を含む風景の巨大な部分を根絶することができます。左右:選択してターゲット領域:攻撃方向のカーソルを決定
-04:31=RCプレーンは箱を収集したり、遠く離れた豚を攻撃するのに理想的な武器です。どちらの敵にそれを操縦するか、最初のいくつかの爆弾をドロップします。攻撃:ワルキューレが戦闘に乗りましょう左右:平面ステアジャンプ平面またはドロップロング爆弾を起動します。
-04:32=低重力はどんなダイエットよりも効果的です!高く、長い距離を飛び越えたり、敵がさらに飛ぶしましょう。攻撃:アクティブ
-04:33=時には、いくつかのより多くのダメージを与えるためにその少し余分なブーストをちょうど必要があります。攻撃:アクティブ
-04:34=私に触れることができない!攻撃:アクティブ
-04:35=時には時間が早すぎる実行している。あなたの攻撃を完了するために、いくつかの余分な秒をつかむ。攻撃:アクティブ
-04:36=さて、時にはあなたが目指すのはあまりにも悪いです。現代の技術を使用していくつかの支援を得る。攻撃:アクティブ
-04:37=日光を恐れてはいけません。それはちょうど1ターン持続しますが、あなたが他の豚に何のダメージを吸収することができるようになります。攻撃:アクティブ
-04:38=スナイパーライフルは、あなたの全体の兵器庫の中で最も壊滅的な武器になります、しかし、それは接近戦で非常に効果的です。ダメージは、そのターゲットまでの距離とともに増加を与えた。攻撃:シュート(回)
-04:39=空飛ぶ円盤を使用してマップの他の部分に飛ぶ。これは、マスターユーティリティのハード戦場のほぼ任意の位置に行くことができるようになりました。攻撃:最大アクティブ左右:ドロップ手榴弾または類似の武器:一方向にロングジャンプ力を適用します。
-04:40=(すぐになる)、燃焼液で満たされたこのボトルを使用して、火災のいくつかの地を設定します。攻撃:より多くの電力を使って撮影するホールド
-04:41=証拠の性質も、空飛ぶ円盤を上回るかもしれません。バーディは、豚を持ち歩くとあなたの敵に卵をドロップすることができます!バーディーを使用すると、あなたのターンの時間に食べるように、迅速である!攻撃:およびドロップ卵アップ左右:一方向にフラップ
-04:42=この携帯ポータル装置は、瞬時に、あなたの敵、または地形上の2点間のあなたの武器あなたを輸送することが可能です。賢明にそれを使用して、キャンペーンがあります...大成功!攻撃:サイクルポータルの色:ポータルスイッチを撃つ
-04:43=あなたの音楽デビュー爆発を成功させる!天からピアノをドロップしますが、注意してください...誰かがそれを再生する必要があり、それはあなたの人生を要するかもしれない!カーソル:選択してターゲット領域F1-F9キーを押して:ピアノを弾く
-04:44=これはただのチーズではなく、生物兵器だ!タイマーがゼロに達すると、それは間違いなく臭いをタッチする誰もが不幸に毒されたら、それは被害の膨大な量が発生することはありません!1-5:セットグレネードのタイマー攻撃:より多くの電力をスローするようにホールド
-04:45=すべてのそれらの物理学のクラスは最終的に報われている、あなたの敵に壊滅的な正弦波を起動します。気を付けろ、この武器は非常にキックをパックします。(この武器は不完全です)攻撃力:シュート
-04:46=液体炎を非常に暑いとあなたの敵をカバーしています。ほのぼの!アタックを上下にアクティブにします。左右を目指して進みます:唾の電源を変更します。
-04:47=2先端のとがった、卑劣な、粘着地雷の楽しみを倍増。連鎖反応を設定するか(あるいは両方!)攻撃を守る:より多くの電力(倍)で撮影するホールド
-04:48=なぜモルすべての虐待を取得する必要があります?豚をは、単に楽しみとしてすることができます!このハンマーから良い打撃は豚の健康状態の3分の1をオフに剃るし、それらを地下に突入します。攻撃:アクティブ
-04:49=あなたの友人を復活させる!しかし、これはまたあなたの敵を復活させること注意してください。攻撃:ゆっくりと復活させるために押された攻撃に注意してください。復活を加速
-04:50=誰かが地下に隠れている?ドリルのストライキでそれらを掘る!タイマーは、それを掘る方法をはるかに制御します。
-04:51=泥のボールを投げつけることによって自由なショットで取得します。刺されは、ビット、豚をバックノックする。
+04:14=高所恐怖症?優れたパラシュートをつかむ。|それはあなたが遠すぎたら落ちる展開と秋のダメージを受けてから豚を保存します。|攻撃:ドロップ手榴弾または類似の武器:パラシュートロングジャンプを伸ばし
+04:15=爆撃の実行を使用して敵を攻撃する飛行機の中で呼び出します。|左右:選択してターゲット領域:攻撃方向のカーソルを決定
+04:16=ターゲットエリアにいくつかの鉱山をドロップするには飛行機の中で呼び出します。|左右:選択してターゲット領域:攻撃方向のカーソルを決定
+04:17=避難が必要ですか?あなたがカバー付与固体地面にトンネルを掘るためにブロートーチを使用しています。|攻撃の開始または停止掘り
+04:18=追加の保護が必要な場合、または地面を通過したいですか?好きなように、いくつかの桁に置きます。|有効な位置に配置桁:左右:カーソルを配置する選択桁
+04:19=それはあなたが数秒以内に危険な状況から豚を保存することができますように、右瞬間テレポーテーションで使用するほぼすべての武器をより強力にすることができます。|カーソル:選択してターゲット領域
+04:20=別の豚と、現在のターンを再生することができます。|攻撃:スイッチング豚を有効にする
+04:21=インパクト時に複数の爆弾を解放します手榴弾のような弾丸を撃つ。|攻撃:フルパワーで撃つ
+04:22=だけでなく、インディジョーンズのために!|鞭は多くの状況で有用な武器である。|あなたが崖から誰かを突き出すしたい場合は特に。|攻撃:あなたの前にストライクのすべて
+04:23=あなたが失うものは何もない場合、これはかなり便利かもしれません。|彼の方法上のすべてを傷つけると終了時に爆発し、特定の方向に彼を起動することで、豚を生け贄に捧げる。|攻撃:壊滅的な、致命的な攻撃を開始
+04:24=誕生日おめでとう!|このケーキを起動し、それが右の敵の隣に歩いて、彼らが爆発的パーティを持たせてみましょう。|ケーキは、ほぼすべての地形を通過することができますが、彼は以前、この方法を爆発させるかもしれません。|攻撃:ケーキを起動するか、停止させると爆発する
+04:25=(そして、いくつかのギャップや穴)が豚に向かってジャンプすることがあなたの敵を取得するには、この変装キットを使用しています。|攻撃:キットを使用して、別の豚を誘惑しよう
+04:26=あなたの敵で、このジューシーなスイカをスローします。|タイマーの期限が切れると、それはいくつかの爆発的な断片に分割されます。|1-5:セットスイカのタイマー攻撃:より多くの電力を使って撮影するホールド
+04:27=この悪魔のよう爆発を使用して、あなたの対戦相手に業火の雨してみましょう。|近すぎる小さな火災が長く続くかもしれないと爆発に得ることはありません。|攻撃:より多くの電力を使って撮影するホールド
+04:28=このロケットを打ち上げた後の短い時間、それは固体地面を掘削を開始し、そのヒューズがトリガされると爆発するか、再び再浮上します。|攻撃:より多くの電力を使って撮影するホールド
+04:29=これは小さな子供のためのものではありません!|ボール銃は爆薬を充填した小さな色のボールのトンを発生させます。|攻撃:アップダウン、フルパワーでシュートを目指して進みます
+04:30=強力なナパームストライキを起動するには飛行機の中で呼び出します。|適切にこの攻撃を目指してそこに座って不運な豚を含む風景の巨大な部分を根絶することができます。|左右:選択してターゲット領域:攻撃方向のカーソルを決定
+04:31=RCプレーンは箱を収集したり、遠く離れた豚を攻撃するのに理想的な武器です。|どちらの敵にそれを操縦するか、最初のいくつかの爆弾をドロップします。|攻撃:ワルキューレが戦闘に乗りましょう左右:平面ステアジャンプ平面またはドロップロング爆弾を起動します。
+04:32=低重力はどんなダイエットよりも効果的です!|高く、長い距離を飛び越えたり、敵がさらに飛ぶしましょう。|攻撃:アクティブ
+04:33=時には、いくつかのより多くのダメージを与えるためにその少し余分なブーストをちょうど必要があります。|攻撃:アクティブ
+04:34=私に触れることができない!|攻撃:アクティブ
+04:35=時には時間が早すぎる実行している。|あなたの攻撃を完了するために、いくつかの余分な秒をつかむ。|攻撃:アクティブ
+04:36=さて、時にはあなたが目指すのはあまりにも悪いです。|現代の技術を使用していくつかの支援を得る。|攻撃:アクティブ
+04:37=日光を恐れてはいけません。|それはちょうど1ターン持続しますが、あなたが他の豚に何のダメージを吸収することができるようになります。|攻撃:アクティブ
+04:38=スナイパーライフルは、あなたの全体の兵器庫の中で最も壊滅的な武器になります、しかし、それは接近戦で非常に効果的です。|ダメージは、そのターゲットまでの距離とともに増加を与えた。|攻撃:シュート(回)
+04:39=空飛ぶ円盤を使用してマップの他の部分に飛ぶ。|これは、マスターユーティリティのハード戦場のほぼ任意の位置に行くことができるようになりました。|攻撃:最大アクティブ左右:ドロップ手榴弾または類似の武器:一方向にロングジャンプ力を適用します。
+04:40=(すぐになる)、燃焼液で満たされたこのボトルを使用して、火災のいくつかの地を設定します。|攻撃:より多くの電力を使って撮影するホールド
+04:41=証拠の性質も、空飛ぶ円盤を上回るかもしれません。|バーディは、豚を持ち歩くとあなたの敵に卵をドロップすることができます!|バーディーを使用すると、あなたのターンの時間に食べるように、迅速である!|攻撃:およびドロップ卵アップ左右:一方向にフラップ
+04:42=この携帯ポータル装置は、瞬時に、あなたの敵、または地形上の2点間のあなたの武器あなたを輸送することが可能です。|賢明にそれを使用して、キャンペーンがあります...大成功!|攻撃:サイクルポータルの色:ポータルスイッチを撃つ
+04:43=あなたの音楽デビュー爆発を成功させる!|天からピアノをドロップしますが、注意してください...誰かがそれを再生する必要があり、それはあなたの人生を要するかもしれない!|カーソル:選択してターゲット領域F1-F9キーを押して:ピアノを弾く
+04:44=これはただのチーズではなく、生物兵器だ!|タイマーがゼロに達すると、それは間違いなく臭いをタッチする誰もが不幸に毒されたら、それは被害の膨大な量が発生することはありません!|1-5:セットグレネードのタイマー攻撃:より多くの電力をスローするようにホールド
+04:45=すべてのそれらの物理学のクラスは最終的に報われている、あなたの敵に壊滅的な正弦波を起動します。|気を付けろ、この武器は非常にキックをパックします。|(この武器は不完全です)攻撃力:シュート
+04:46=液体炎を非常に暑いとあなたの敵をカバーしています。|ほのぼの!|アタックを上下にアクティブにします。|左右を目指して進みます:唾の電源を変更します。
+04:47=2先端のとがった、卑劣な、粘着地雷の楽しみを倍増。|連鎖反応を設定するか(あるいは両方!|)攻撃を守る:より多くの電力(倍)で撮影するホールド
+04:48=なぜモルすべての虐待を取得する必要があります?豚をは、単に楽しみとしてすることができます!|このハンマーから良い打撃は豚の健康状態の3分の1をオフに剃るし、それらを地下に突入します。|攻撃:アクティブ
+04:49=あなたの友人を復活させる!|しかし、これはまたあなたの敵を復活させること注意してください。|攻撃:ゆっくりと復活させるために押された攻撃に注意してください。|復活を加速
+04:50=誰かが地下に隠れている?ドリルのストライキでそれらを掘る!|タイマーは、それを掘る方法をはるかに制御します。
+04:51=泥のボールを投げつけることによって自由なショットで取得します。|刺されは、ビット、豚をバックノックする。
 04:52=UNUSED
-04:53=あなたの仲間が単独で戦うために残しながら、時間と空間を介して冒険に出る。いつでも返すように準備する、または突然死の場合、または、それらはすべて敗北しています。免責事項。あなたは一人である場合は、突然死で機能するか、キングである場合ではありません。
+04:53=あなたの仲間が単独で戦うために残しながら、時間と空間を介して冒険に出る。|いつでも返すように準備する、または突然死の場合、または、それらはすべて敗北しています。|免責事項。|あなたは一人である場合は、突然死で機能するか、キングである場合ではありません。
 04:54=INCOMPLETE
-04:55=スティッキーフレークのストリームをスプレー。トンネルを封鎖、敵を埋める、ブリッジを構築します。あなたが上の任意のを取得しないように注意してください!
+04:55=スティッキーフレークのストリームをスプレー。|トンネルを封鎖、敵を埋める、ブリッジを構築します。|あなたが上の任意のを取得しないように注意してください!
 
 ; Game goal strings
 05:00=ゲームモード