merge
authorStepan777 <stepik-777@mail.ru>
Thu, 07 Jun 2012 17:42:32 +0400
changeset 7194 d8e68cbca7ee
parent 7180 53ffc8853008 (current diff)
parent 7192 e6c379b486d5 (diff)
child 7196 4fba5519c37f
merge
hedgewars/SDLh.pas
hedgewars/uCommandHandlers.pas
hedgewars/uGearsHedgehog.pas
hedgewars/uInputHandler.pas
hedgewars/uTeams.pas
hedgewars/uTypes.pas
hedgewars/uUtils.pas
hedgewars/uWorld.pas
--- a/hedgewars/SDLh.pas	Mon Jun 04 21:32:30 2012 +0400
+++ b/hedgewars/SDLh.pas	Thu Jun 07 17:42:32 2012 +0400
@@ -270,6 +270,19 @@
     AShift = 0;
 {$ENDIF}
 
+    KMOD_NONE   = $0000;
+    KMOD_LSHIFT = $0001;
+    KMOD_RSHIFT = $0002;
+    KMOD_LCTRL  = $0040;
+    KMOD_RCTRL  = $0080;
+    KMOD_LALT   = $0100;
+    KMOD_RALT   = $0200;
+    KMOD_LMETA  = $0400;
+    KMOD_RMETA  = $0800;
+    KMOD_NUM    = $1000;
+    KMOD_CAPS   = $2000;
+    KMOD_MODE   = $4000;
+
     {* SDL_mixer *}
     MIX_MAX_VOLUME = 128;
     MIX_INIT_FLAC  = $00000001;
--- a/hedgewars/uAI.pas	Mon Jun 04 21:32:30 2012 +0400
+++ b/hedgewars/uAI.pas	Thu Jun 07 17:42:32 2012 +0400
@@ -129,8 +129,10 @@
         ThreadSwitch();
 {$ENDIF}       
         repeat
-        if (CanUseAmmo[a]) and
-            ((not isMoved) or ((AmmoTests[a].flags and amtest_OnTurn) = 0)) then
+        if (CanUseAmmo[a]) 
+            and ((not isMoved) or ((AmmoTests[a].flags and amtest_OnTurn) = 0)) 
+            and ((i = 0) or ((AmmoTests[a].flags and amtest_NoTarget) = 0)) 
+            then
             begin
 {$HINTS OFF}
             Score:= AmmoTests[a].proc(Me, Targets.ar[i].Point, BotLevel, ap);
@@ -181,8 +183,8 @@
         if a = High(TAmmoType) then
             a:= Low(TAmmoType)
         else inc(a)
-        until (a = aa) or (CurrentHedgehog^.MultiShootAttacks > 0) or // shooting same weapon
-        StopThinking
+        until (a = aa) or (CurrentHedgehog^.MultiShootAttacks > 0) {shooting same weapon}
+            or StopThinking
         end
 end;
 
--- a/hedgewars/uAIAmmoTests.pas	Mon Jun 04 21:32:30 2012 +0400
+++ b/hedgewars/uAIAmmoTests.pas	Thu Jun 07 17:42:32 2012 +0400
@@ -21,7 +21,9 @@
 unit uAIAmmoTests;
 interface
 uses SDLh, uConsts, uFloat, uTypes;
-const amtest_OnTurn = $00000001;
+const 
+    amtest_OnTurn   = $00000001; // from one position
+    amtest_NoTarget = $00000002; // each pos, but no targetting
 
 var windSpeed: real;
 
@@ -68,9 +70,9 @@
             (proc: nil;              flags: 0), // amMine
             (proc: @TestDesertEagle; flags: 0), // amDEagle
             (proc: nil;              flags: 0), // amDynamite
-            (proc: @TestFirePunch;   flags: 0), // amFirePunch
-            (proc: @TestWhip;        flags: 0), // amWhip
-            (proc: @TestBaseballBat; flags: 0), // amBaseballBat
+            (proc: @TestFirePunch;   flags: amtest_NoTarget), // amFirePunch
+            (proc: @TestWhip;        flags: amtest_NoTarget), // amWhip
+            (proc: @TestBaseballBat; flags: amtest_NoTarget), // amBaseballBat
             (proc: nil;              flags: 0), // amParachute
             (proc: @TestAirAttack;   flags: amtest_OnTurn), // amAirAttack
             (proc: nil;              flags: 0), // amMineStrike
@@ -105,7 +107,7 @@
             (proc: @TestShotgun;     flags: 0), // amSineGun
             (proc: nil;              flags: 0), // amFlamethrower
             (proc: @TestGrenade;     flags: 0), // amSMine
-            (proc: @TestHammer;      flags: 0), // amHammer
+            (proc: @TestHammer;      flags: amtest_NoTarget), // amHammer
             (proc: nil;              flags: 0), // amResurrector
             (proc: nil;              flags: 0), // amDrillStrike
             (proc: nil;              flags: 0), // amSnowball
@@ -640,7 +642,7 @@
 ap.ExplR:= 0;
 x:= hwFloat2Float(Me^.X);
 y:= hwFloat2Float(Me^.Y);
-if (Level > 2) or (Abs(trunc(x) - Targ.X) + Abs(trunc(y) - Targ.Y) > 25) then
+if (Level > 2) then
     exit(BadTurn);
 
 ap.Time:= 0;
@@ -710,8 +712,7 @@
 else TestFirePunch:= BadTurn;
 end;
 
-// TODO: TestWhip, TestFirepunch and TestBaseballBat could be called only once at each position 
-// (now they're called for each possible target in each position)
+
 function TestWhip(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
 var valueResult, v1, v2: LongInt;
     x, y: real;
@@ -723,9 +724,6 @@
 x:= hwFloat2Float(Me^.X);
 y:= hwFloat2Float(Me^.Y);
 
-if(abs(Targ.X - x) > 50) or (abs(Targ.Y - y) > 30) then // we're way too far from our target
-    exit(BadTurn);
-    
 // check left direction
 {first RateShove checks fartherest of two whip's AmmoShove attacks 
 to encourage distant attacks (damaged hog is excluded from view of second 
@@ -775,10 +773,7 @@
 ap.Power:= 1;
 ap.Angle:= 0;
          
-if (Abs(hwRound(Me^.X) + hwSign(Me^.dX) * 10 - Targ.X) + Abs(hwRound(Me^.Y) - Targ.Y) > 20) then
-    rate:= 0
-else
-    rate:= RateHammer(Me);
+rate:= RateHammer(Me);
 if rate = 0 then
     rate:= BadTurn;
 TestHammer:= rate;
--- a/hedgewars/uCommandHandlers.pas	Mon Jun 04 21:32:30 2012 +0400
+++ b/hedgewars/uCommandHandlers.pas	Thu Jun 07 17:42:32 2012 +0400
@@ -436,7 +436,7 @@
         end
     else
         TryDo(checksum = lastTurnChecksum, 'Desync detected', true);
-    AddFileLog('Doing SwitchHedgehog: time '+inttostr(GameTicks));
+    AddFileLog('Next turn: time '+inttostr(GameTicks));
 end;
 
 procedure chTimer(var s: shortstring);
--- a/hedgewars/uConsts.pas	Mon Jun 04 21:32:30 2012 +0400
+++ b/hedgewars/uConsts.pas	Thu Jun 07 17:42:32 2012 +0400
@@ -147,6 +147,7 @@
     cBlowTorchC    = 6;
 
     cKeyMaxIndex = 1023;
+    cKbdMaxIndex = 65536;//need more room for the modifier keys
 
     cHHFileName = 'Hedgehog';
     cCHFileName = 'Crosshair';
--- a/hedgewars/uGears.pas	Mon Jun 04 21:32:30 2012 +0400
+++ b/hedgewars/uGears.pas	Thu Jun 07 17:42:32 2012 +0400
@@ -363,11 +363,11 @@
 
                 FreeActionsList; // could send -left, -right and similar commands, so should be called before /nextturn
 
+                ParseCommand('/nextturn', true);
                 SwitchHedgehog;
 
                 AfterSwitchHedgehog;
-                bBetweenTurns:= false;
-                ParseCommand('/nextturn', true)
+                bBetweenTurns:= false
                 end;
             step:= Low(step)
             end;
--- a/hedgewars/uGearsHedgehog.pas	Mon Jun 04 21:32:30 2012 +0400
+++ b/hedgewars/uGearsHedgehog.pas	Thu Jun 07 17:42:32 2012 +0400
@@ -707,12 +707,10 @@
     if (Gear^.Message and gmLeft  )<>0 then
         Gear^.dX:= -cLittle else
     if (Gear^.Message and gmRight )<>0 then
-        Gear^.dX:=  cLittle else exit;
+        Gear^.dX:=  cLittle 
+        else exit;
 
-    if (Gear^.Message and (gmLeft or gmRight)) <> 0 then
-        begin
-        StepSoundTimer:= cHHStepTicks;
-        end;
+    StepSoundTimer:= cHHStepTicks;
    
     GHStepTicks:= cHHStepTicks;
     if PrevdX <> hwSign(Gear^.dX) then
@@ -837,6 +835,7 @@
     if (CurrentHedgehog^.Gear = Gear)
         and (hwSqr(Gear^.dX) + hwSqr(Gear^.dY) > _0_003) then 
         begin
+        // TODO: why so aggressive at setting FollowGear when falling?
         FollowGear:= Gear;
         end;
     if isUnderwater then
--- a/hedgewars/uGearsUtils.pas	Mon Jun 04 21:32:30 2012 +0400
+++ b/hedgewars/uGearsUtils.pas	Thu Jun 07 17:42:32 2012 +0400
@@ -483,13 +483,13 @@
     RecountTeamHealth(tempTeam);
 end;
 
-function CountNonZeroz(x, y, r, c: LongInt): LongInt;
+function CountNonZeroz(x, y, r, c: LongInt; mask: LongWord): LongInt;
 var i: LongInt;
     count: LongInt = 0;
 begin
     if (y and LAND_HEIGHT_MASK) = 0 then
         for i:= max(x - r, 0) to min(x + r, LAND_WIDTH - 4) do
-            if Land[y, i] <> 0 then
+            if Land[y, i] and mask <> 0 then
             begin
                 inc(count);
                 if count = c then
@@ -531,9 +531,10 @@
     ar2: array[0..1023] of TPoint;
     cnt, cnt2: Longword;
     delta: LongInt;
-    reallySkip, tryAgain: boolean;
+    ignoreNearObjects, ignoreOverlap, tryAgain: boolean;
 begin
-reallySkip:= false; // try not skipping proximity at first
+ignoreNearObjects:= false; // try not skipping proximity at first
+ignoreOverlap:= false; // this not only skips proximity, but allows overlapping objects (barrels, mines, hogs, crates).  Saving it for a 3rd pass.  With this active, winning AI Survival goes back to virtual impossibility
 tryAgain:= true;
 while tryAgain do
     begin
@@ -549,23 +550,27 @@
                 begin
                 repeat
                     inc(y, 2);
-                until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) = 0);
+                until (y >= cWaterLine) or
+                        (not ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FFFF) = 0)) or 
+                        (ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FF00) = 0));
 
                 sy:= y;
 
                 repeat
                     inc(y);
-                until (y >= cWaterLine) or (CountNonZeroz(x, y, Gear^.Radius - 1, 1) <> 0);
+                until (y >= cWaterLine) or
+                        (not ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FFFF) <> 0)) or 
+                        (ignoreOverlap and (CountNonZeroz(x, y, Gear^.Radius - 1, 1, $FF00) <> 0)); 
 
                 if (y - sy > Gear^.Radius * 2)
                     and (((Gear^.Kind = gtExplosives)
                     and (y < cWaterLine)
-                    and (reallySkip or NoGearsToAvoid(x, y - Gear^.Radius, 60, 60))
-                    and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1) > Gear^.Radius))
+                    and (ignoreNearObjects or NoGearsToAvoid(x, y - Gear^.Radius, 60, 60))
+                    and (CountNonZeroz(x, y+1, Gear^.Radius - 1, Gear^.Radius+1, $FFFF) > Gear^.Radius))
                 or
                     ((Gear^.Kind <> gtExplosives)
                     and (y < cWaterLine)
-                    and (reallySkip or NoGearsToAvoid(x, y - Gear^.Radius, 110, 110))
+                    and (ignoreNearObjects or NoGearsToAvoid(x, y - Gear^.Radius, 110, 110))
                     )) then
                     begin
                     ar[cnt].X:= x;
@@ -590,10 +595,12 @@
 
         dec(Delta, 60)
     until (cnt2 > 0) or (Delta < 70);
-    if (cnt2 = 0) and skipProximity and (not reallySkip) then
+    // if either of these has not been tried, do another pass
+    if (cnt2 = 0) and skipProximity and (not ignoreOverlap) then
         tryAgain:= true
     else tryAgain:= false;
-    reallySkip:= true;
+    if ignoreNearObjects then ignoreOverlap:= true;
+    ignoreNearObjects:= true;
     end;
 
 if cnt2 > 0 then
--- a/hedgewars/uInputHandler.pas	Mon Jun 04 21:32:30 2012 +0400
+++ b/hedgewars/uInputHandler.pas	Thu Jun 07 17:42:32 2012 +0400
@@ -25,7 +25,9 @@
 procedure initModule;
 procedure freeModule;
 
-function  KeyNameToCode(name: shortstring): word;
+function  KeyNameToCode(name: shortstring; Modifier: shortstring = ''): LongInt;
+procedure MaskModifier(var code: LongInt; modifier: LongWord);
+procedure MaskModifier(Modifier: shortstring; var code: LongInt);
 procedure ProcessMouse(event: TSDL_MouseButtonEvent; ButtonDown: boolean);
 procedure ProcessKey(event: TSDL_KeyboardEvent); inline;
 procedure ProcessKey(code: LongInt; KeyDown: boolean);
@@ -45,37 +47,66 @@
 implementation
 uses uConsole, uCommands, uMisc, uVariables, uConsts, uUtils, uDebug;
 
-var tkbd: array[0..cKeyMaxIndex] of boolean;
+var tkbd: array[0..cKbdMaxIndex] of boolean;
     quitKeyCode: Byte;
     KeyNames: array [0..cKeyMaxIndex] of string[15];
     CurrentBinds: TBinds;
 
-function KeyNameToCode(name: shortstring): word;
-var code: Word;
+function KeyNameToCode(name: shortstring; Modifier: shortstring): LongInt;
+var code: LongInt;
 begin
     name:= LowerCase(name);
     code:= cKeyMaxIndex;
     while (code > 0) and (KeyNames[code] <> name) do dec(code);
+
+    MaskModifier(Modifier, code);
     KeyNameToCode:= code;
 end;
 
+procedure MaskModifier(var code: LongInt; Modifier: LongWord);
+begin
+    code:= code or (modifier shl 10);
+end;
+
+procedure MaskModifier(Modifier: shortstring; var code: LongInt);
+var mod_ : shortstring;
+    ModifierCount, i: LongInt;
+    c : char;
+begin
+if Modifier = '' then exit;
+ModifierCount:= 0;
+for c in Modifier do
+    if(c = ':') then inc(ModifierCount);
+
+SplitByChar(Modifier, mod_, ':');//remove the first mod: part
+Modifier:= mod_;
+for i:= 0 to ModifierCount do
+    begin 
+    mod_:= '';
+    SplitByChar(Modifier, mod_, ':');
+    if (Modifier = 'lshift')                    then code:= code or (KMOD_LSHIFT shl 10);
+    if (Modifier = 'rshift')                    then code:= code or (KMOD_RSHIFT shl 10);
+    if (Modifier = 'lalt')                      then code:= code or (KMOD_LALT   shl 10);
+    if (Modifier = 'ralt')                      then code:= code or (KMOD_RALT   shl 10);
+    if (Modifier = 'lctrl') or (mod_ = 'lmeta') then code:= code or (KMOD_LCTRL  shl 10);
+    if (Modifier = 'rctrl') or (mod_ = 'rmeta') then code:= code or (KMOD_RCTRL  shl 10);
+    Modifier:= mod_;
+    end;
+end;
+
 procedure ProcessKey(code: LongInt; KeyDown: boolean);
 var
     Trusted: boolean;
     s      : string;
 begin
-
 if not(tkbd[code] xor KeyDown) then exit;
 tkbd[code]:= KeyDown;
 
-
 hideAmmoMenu:= false;
 Trusted:= (CurrentTeam <> nil)
           and (not CurrentTeam^.ExtDriven)
           and (CurrentHedgehog^.BotLevel = 0);
 
-
-
 // ctrl/cmd + q to close engine and frontend
 if(KeyDown and (code = quitKeyCode)) then
     begin
@@ -109,8 +140,12 @@
 end;
 
 procedure ProcessKey(event: TSDL_KeyboardEvent); inline;
+var code: LongInt;
 begin
-    ProcessKey(event.keysym.sym, event.type_ = SDL_KEYDOWN);
+    code:= event.keysym.sym;
+    MaskModifier(code, event.keysym.modifier);
+    
+    ProcessKey(code, event.type_ = SDL_KEYDOWN);
 end;
 
 procedure ProcessMouse(event: TSDL_MouseButtonEvent; ButtonDown: boolean);
@@ -132,7 +167,7 @@
 procedure ResetKbd;
 var t: LongInt;
 begin
-for t:= 0 to cKeyMaxIndex do
+for t:= 0 to cKbdMaxIndex do
     if tkbd[t] then
         ProcessKey(t, False);
 end;
@@ -240,11 +275,19 @@
 end;
 
 procedure SetBinds(var binds: TBinds);
+{$IFNDEF MOBILE}
+var
+    t: LongInt;
+{$ENDIF}
 begin
 {$IFDEF MOBILE}
     binds:= binds; // avoid hint
     CurrentBinds:= DefaultBinds;
 {$ELSE}
+for t:= 0 to cKbdMaxIndex do
+    if (CurrentBinds[t] <> binds[t]) and tkbd[t] then
+        ProcessKey(t, False);
+
     CurrentBinds:= binds;
 {$ENDIF}
 end;
--- a/hedgewars/uTeams.pas	Mon Jun 04 21:32:30 2012 +0400
+++ b/hedgewars/uTeams.pas	Thu Jun 07 17:42:32 2012 +0400
@@ -248,8 +248,6 @@
     FollowGear:= Gear
     end;
 
-ResetKbd;
-
 if (GameFlags and gfDisableWind) = 0 then
     begin
     cWindSpeed:= rndSign(GetRandomf * 2 * cMaxWindSpeed);
@@ -554,22 +552,33 @@
 end;
 
 procedure chBind(var id: shortstring);
-var s: shortstring;
+var KeyName, Modifier, tmp: shortstring;
     b: LongInt;
 begin
-s:= '';
+KeyName:= '';
+Modifier:= '';
+
 if CurrentTeam = nil then
     exit;
-SplitBySpace(id, s);
-if s[1]='"' then
-    Delete(s, 1, 1);
-if s[byte(s[0])]='"' then
-    Delete(s, byte(s[0]), 1);
-b:= KeyNameToCode(id);
+
+if(Pos('mod:', id) <> 0)then
+    begin
+    tmp:= '';
+    SplitBySpace(id, tmp);
+    Modifier:= id;
+    id:= tmp;
+    end;
+
+SplitBySpace(id, KeyName);
+if KeyName[1]='"' then
+    Delete(KeyName, 1, 1);
+if KeyName[byte(KeyName[0])]='"' then
+    Delete(KeyName, byte(KeyName[0]), 1);
+b:= KeyNameToCode(id, Modifier);
 if b = 0 then
     OutError(errmsgUnknownVariable + ' "' + id + '"', false)
 else
-    CurrentTeam^.Binds[b]:= s
+    CurrentTeam^.Binds[b]:= KeyName;
 end;
 
 procedure chTeamGone(var s:shortstring);
--- a/hedgewars/uTouch.pas	Mon Jun 04 21:32:30 2012 +0400
+++ b/hedgewars/uTouch.pas	Thu Jun 07 17:42:32 2012 +0400
@@ -62,8 +62,11 @@
 const
     clickTime = 200;
     nilFingerId = High(TSDL_FingerId);
+    baseRectSize = 96;
 
 var
+    rectSize, halfRectSize: LongInt;
+
     pointerCount : Longword;
     fingers: array of TTouch_Data;
     moveCursor : boolean;
@@ -551,8 +554,10 @@
     x := 0;//avoid compiler hint
     y := 0;
     convertToFingerCoord(x, y, CrosshairX, CrosshairY);
-  isOnCrosshair:= sqrt(sqr(finger.x-x) + sqr(finger.y-y)) < 50;
-//    isOnCrosshair:= isOnRect(x-24, y-24, 48, 48, finger);
+    isOnCrosshair:= isOnRect((x-HalfRectSize), (y-HalfRectSize), RectSize, RectSize, finger);
+    printFinger(finger);
+    WriteLnToConsole(inttostr(finger.x) + '   ' + inttostr(x));
+    WriteLnToConsole(inttostr(x) + '  ' + inttostr(y) + '   ' + inttostr(round(Android_JNI_getDensity() * 10)));
 end;
 
 function isOnCurrentHog(finger: TTouch_Data): boolean;
@@ -562,7 +567,7 @@
     x := 0;
     y := 0;
     convertToFingerCoord(x,y, hwRound(CurrentHedgehog^.Gear^.X), hwRound(CurrentHedgehog^.Gear^.Y));
-    isOnCurrentHog := sqrt(sqr(finger.X-x) + sqr(finger.Y-y)) < 50;
+    isOnCurrentHog:= isOnRect((x-HalfRectSize), (y-HalfRectSize), RectSize, RectSize, finger);
 end;
 
 procedure convertToFingerCoord(var x,y : LongInt; oldX, oldY: LongInt);
@@ -627,12 +632,22 @@
 var
     index: Longword;
     //uRenderCoordScaleX, uRenderCoordScaleY: Longword;
+    density: Single;
 begin
     buttonsDown:= 0;
 
     setLength(fingers, 4);
     for index := 0 to High(fingers) do 
         fingers[index].id := nilFingerId;
+
+{$IFDEF ANDROID}
+    density:= Android_JNI_getDensity();
+{$ELSE}
+    density:= 1.0;
+{$ENDIF}
+
+    rectSize:= round(baseRectSize * density);
+    halfRectSize:= rectSize shl 1;
 end;
 
 begin
--- a/hedgewars/uTypes.pas	Mon Jun 04 21:32:30 2012 +0400
+++ b/hedgewars/uTypes.pas	Thu Jun 07 17:42:32 2012 +0400
@@ -308,7 +308,7 @@
         TeamDamage : Longword;
         end;
 
-    TBinds = array[0..cKeyMaxIndex] of shortstring;
+    TBinds = array[0..cKbdMaxIndex] of shortstring;
     TKeyboardState = array[0..cKeyMaxIndex] of Byte;
 
     PVoicepack = ^TVoicepack;
--- a/hedgewars/uUtils.pas	Mon Jun 04 21:32:30 2012 +0400
+++ b/hedgewars/uUtils.pas	Thu Jun 07 17:42:32 2012 +0400
@@ -24,6 +24,7 @@
 uses uTypes, uFloat, GLunit;
 
 procedure SplitBySpace(var a, b: shortstring);
+procedure SplitByChar(var a, b: shortstring; c: char);
 procedure SplitByChar(var a, b: ansistring; c: char);
 
 {$IFNDEF PAS2C}
@@ -85,11 +86,16 @@
 {$ENDIF}
 var CharArray: array[byte] of Char;
 
+procedure SplitBySpace(var a,b: shortstring);
+begin
+SplitByChar(a,b,' ');
+end;
+
 // should this include "strtolower()" for the split string?
-procedure SplitBySpace(var a, b: shortstring);
+procedure SplitByChar(var a, b: shortstring; c : char);
 var i, t: LongInt;
 begin
-i:= Pos(' ', a);
+i:= Pos(c, a);
 if i > 0 then
     begin
     for t:= 1 to Pred(i) do
--- a/hedgewars/uWorld.pas	Mon Jun 04 21:32:30 2012 +0400
+++ b/hedgewars/uWorld.pas	Thu Jun 07 17:42:32 2012 +0400
@@ -1516,9 +1516,6 @@
             DrawTexture((cScreenWidth shr 1) - 60 - offsetY, offsetX, fpsTexture);
         end;
 
-    if CountTicks >= 1000 then
-        CountTicks:= 0;
-
     // lag warning (?)
     inc(SoundTimerTicks, Lag);
 end;
@@ -1635,7 +1632,10 @@
 {$ENDIF}
 z:= round(200/zoom);
 if not PlacingHogs and (FollowGear <> nil) and (not isCursorVisible) and (not bShowAmmoMenu) and (not fastUntilLag) then
-    if (not autoCameraOn) or ((abs(CursorPoint.X - prevPoint.X) + abs(CursorPoint.Y - prevpoint.Y)) > 4) then
+    if (not autoCameraOn) then
+        FollowGear:= nil
+    else        
+    if ((abs(CursorPoint.X - prevPoint.X) + abs(CursorPoint.Y - prevpoint.Y)) > 4) then
         begin
         FollowGear:= nil;
         prevPoint:= CursorPoint;
@@ -1685,7 +1685,7 @@
     EdgesDist:= cGearScrEdgesDist;
 
 // this generates the border around the screen that moves the camera when cursor is near it
-if isCursorVisible or (FollowGear <> nil) then
+if isCursorVisible or ((FollowGear <> nil) and autoCameraOn) then
     begin
     if CursorPoint.X < - cScreenWidth div 2 + EdgesDist then
         begin
--- a/project_files/Android-build/SDL-android-project/jni/SDL/src/core/android/SDL_android.cpp	Mon Jun 04 21:32:30 2012 +0400
+++ b/project_files/Android-build/SDL-android-project/jni/SDL/src/core/android/SDL_android.cpp	Thu Jun 07 17:42:32 2012 +0400
@@ -638,16 +638,12 @@
     return Android_JNI_FileClose(ctx, true);
 }
 
-/*******************************************************************************
-             Functions called by the hwengine into Java
-*******************************************************************************/
-
-extern "C" float Android_JNI_getDensity(){
+extern "C" int Android_JNI_getDensity(){
     jmethodID mid;
-    jfloat density;
+    jint density;
     //SDLActivity.getDensity()
-    mid = mEnv->GetStaticMethodID(mActivityClass, "getDensity", "()F");
-        if(!mid) return 1.5f;
+    mid = mEnv->GetStaticMethodID(mActivityClass, "getDensity", "()I");
+        if(!mid) return 160;
     density = mEnv->CallStaticFloatMethod(mActivityClass, mid);
     return density;
 
--- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java	Mon Jun 04 21:32:30 2012 +0400
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java	Thu Jun 07 17:42:32 2012 +0400
@@ -403,9 +403,9 @@
 		}
 	}
 	
-	public static float getDensity(){
+	public static int getDensity(){
 		DisplayMetrics dm = SDLActivity.getContext().getResources().getDisplayMetrics();
-		return dm.density;
+		return dm.densityDpi;
 	}
 }
 
--- a/share/hedgewars/Data/Scripts/Multiplayer/WxW.lua	Mon Jun 04 21:32:30 2012 +0400
+++ b/share/hedgewars/Data/Scripts/Multiplayer/WxW.lua	Thu Jun 07 17:42:32 2012 +0400
@@ -598,7 +598,7 @@
 	roundN = roundN + 1
 	if roundN < 2 then
 		TurnTimeLeft = -1
-		SetInputMask(band(0xFFFFFFFF, bnot(gmAnimate+gmAttack+gmDown+gmHJump+gmLeft+gmLJump+gmPrecise+gmRight+gmSlot+gmSwitch+gmTimer+gmUp+gmWeapon)))
+		SetInputMask(0)
 		allowCrate = false
 		HandleStartingStage() -- new
 	end
@@ -670,7 +670,7 @@
 				then
 					SetInputMask(0xFFFFFFFF)
 				elseif ropeG == nil then
-					SetInputMask(band(0xFFFFFFFF, bnot(gmAttack)))
+					SetInputMask(bnot(gmAttack))
 				end
 			end