hedgewars/uVariables.pas
branchui-scaling
changeset 15283 c4fd2813b127
parent 13389 24b531dcebe7
parent 15267 22f2fd8a3d2c
child 15663 d92eeb468dad
--- a/hedgewars/uVariables.pas	Wed May 16 18:22:28 2018 +0200
+++ b/hedgewars/uVariables.pas	Wed Jul 31 23:14:27 2019 +0200
@@ -41,8 +41,8 @@
     ipcPort            : Word;
     AprilOne           : boolean;
     cFullScreen        : boolean;
-    cLocaleFName       : shortstring;
-    cLocale            : shortstring;
+    cLanguageFName     : shortstring;
+    cLanguage          : shortstring;
     cTimerInterval     : LongInt;
     PathPrefix         : ansistring;
     UserPathPrefix     : ansistring;
@@ -55,6 +55,7 @@
 
     cAltDamage         : boolean;
     cReducedQuality    : LongWord;
+    cHolidaySilliness  : boolean;
     UserNick           : shortstring;
     recordFileName     : shortstring;
     cReadyDelay        : Longword;
@@ -78,6 +79,9 @@
     isInMultiShoot  : boolean;
     isSpeed         : boolean;
     isAFK           : boolean;
+    isShowMission   : boolean;
+    isShowGearInfo  : boolean;
+    isForceMission  : boolean;
     SpeedStart      : LongWord;
 
     fastUntilLag    : boolean;
@@ -86,7 +90,9 @@
 
     CheckSum        : LongWord;
     CampaignVariable: shortstring;
+    MissionVariable : shortstring;
     GameTicks       : LongWord;
+    OuchTauntTimer  : LongWord; // Timer which blocks sndOuch from being played too often and fast
     GameState       : TGameState;
     GameType        : TGameType;
     InputMask       : LongWord;
@@ -101,12 +107,17 @@
     IsGetAwayTime   : boolean;
     GameOver        : boolean;
     cSuddenDTurns   : LongInt;
+    LastSuddenDWarn : LongInt; // last round in which the last SD warning appeared. -2 = no warning so far
+    cInitHealth     : LongInt; // initial hedgehog health (from game scheme. note the real hog health is sent directly
+                               // from frontend, this is only used to inform Lua scripts)
     cDamagePercent  : LongInt;
     cMineDudPercent : LongWord;
     cTemplateFilter : LongInt;
     cFeatureSize    : LongInt;
     cMapGen         : TMapGen;
     cRopePercent    : LongWord;
+    cRopeNodeStep   : LongWord;
+    cRopeLayers     : LongInt;
     cGetAwayTime    : LongWord;
 
     cAdvancedMapGenMode: boolean;
@@ -125,8 +136,9 @@
 
     cTagsMask        : byte;
     cPrevTagsMask    : byte;
-    zoom             : GLfloat;
-    ZoomValue        : GLfloat;
+    zoom             : GLfloat; // current zoom
+    ZoomValue        : GLfloat; // aimed zoom
+    UserZoom         : GLfloat; // user-chosen initial and default zoom
     ChatScaleValue   : real;
     cDefaultChatScale: real;
     UIScaleValue     : real;
@@ -162,6 +174,8 @@
     cScreenSpace          : Longword;
 
     cCaseFactor     : Longword;
+    cMaxCaseDrops   : Longword; // Max. number of crates which can be in the game when dropping
+
     cLandMines      : Longword;
     cAirMines       : Longword;
     cExplosives     : Longword;
@@ -169,16 +183,21 @@
     cScriptName     : shortstring;
     cScriptParam    : shortstring;
     cSeed           : shortstring;
+    cIsSoundEnabled : boolean; // If the sound system is enabled
     cVolumeDelta    : LongInt;
+    cVolumeUpKey    : boolean;
+    cVolumeDownKey  : boolean;
     cMuteToggle     : boolean; // Mute toggle requested
     cHasFocus       : boolean;
     cInactDelay     : Longword;
 
     bBetweenTurns   : boolean;
     bWaterRising    : boolean;
+    bDuringWaterRise: boolean;
 
     CrosshairX      : LongInt;
     CrosshairY      : LongInt;
+    CrosshairGear   : PGear;
     CursorMovementX : LongInt;
     CursorMovementY : LongInt;
     cWaveHeight     : LongInt;
@@ -203,7 +222,9 @@
     cMaxZoomLevel   : real;
     cMinZoomLevel   : real;
     cZoomDelta      : real;
+    cZoomDeltaSmall : real;
     cMinMaxZoomLevelDelta : real;
+    cDemoClockFPSOffsetY : LongInt;
 
 
     flagMakeCapture : boolean;
@@ -215,9 +236,11 @@
 
     WaterColorArray : array[0..7] of HwColor4f;
     SDWaterColorArray : array[0..7] of HwColor4f;
+    ClanColorArray : array[0..Pred(cClanColors)] of Longword;
 
     TargetCursorPoint     : TPoint;
     CursorPoint           : TPoint;
+    CursorPointDelta      : TPoint;
     TargetPoint           : TPoint;
 
     ScreenFade      : TScreenFade;
@@ -259,6 +282,12 @@
     LuaEndTurnRequested: boolean;
     LuaNoEndTurnTaunts: boolean;
 
+    // whether Lua requested to pause the clock
+    LuaClockPaused: boolean;
+
+    // whether /lua command was used
+    LuaCmdUsed: boolean;
+
     MaskedSounds : array[TSound] of boolean;
 
     LastVoice : TVoice;
@@ -274,10 +303,12 @@
 //Buttons
 {$IFDEF USE_TOUCH_INTERFACE}
     buttonScale: GLFloat;
+    bounceButtonPressed: boolean;
 
     arrowUp, arrowDown, arrowLeft, arrowRight : TOnScreenWidget;
     firebutton, jumpWidget, AMWidget          : TOnScreenWidget;
     pauseButton, utilityWidget                : TOnScreenWidget;
+    utilityWidget2                            : TOnScreenWidget;
 {$ENDIF}
 
 
@@ -291,7 +322,7 @@
         '//',                            // ptData
         '/Graphics',                     // ptGraphics
         '/Themes',                       // ptThemes
-        '/Themes/Bamboo',                // ptCurrTheme
+        '/Themes/Nature',                // ptCurrTheme
         '/Config',                       // ptConfig
         '/Config/Teams',                 // ptTeams
         '/Maps',                         // ptMaps
@@ -310,7 +341,9 @@
         '/Missions/Maps',                // ptMissionMaps
         '/Graphics/SuddenDeath',         // ptSuddenDeath
         '/Graphics/Buttons',             // ptButton
-        '/Shaders'                       // ptShaders
+        '/Shaders',                      // ptShaders
+        '/Sounds/voices/Default',        // ptDefaultVoice
+        '/misc'                          // ptMisc
     );
 
 var
@@ -451,8 +484,8 @@
             Width:  48; Height: 48; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprParachute
             (FileName:     'Target'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
             Width:  32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprTarget
-            (FileName:   'RopeNode'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
-            Width:   6; Height:  6; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpHighest; getDimensions: false; getImageDimensions: true),// sprRopeNode
+            (FileName:   'RopeNode'; Path: ptCurrTheme; AltPath: ptGraphics; Texture: nil; Surface: nil;
+            Width:   16; Height:  16; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpHighest; getDimensions: false; getImageDimensions: true),// sprRopeNode
             (FileName:   'thinking'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
             Width:  32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpLowest; getDimensions: false; getImageDimensions: true),// sprQuestion
             (FileName:   'PowerBar'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
@@ -486,6 +519,8 @@
             Width: 128; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprTargetButton
             (FileName: 'switchbutton'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
             Width: 128; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprSwitchButton
+            (FileName: 'bouncebutton'; Path: ptButtons; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width: 128; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpHigh; getDimensions: false; getImageDimensions: true), // sprBounceButton
 {$ENDIF}
             (FileName:      'Flake'; Path:ptCurrTheme; AltPath: ptNone; Texture: nil; Surface: nil;
             Width:  64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpHighest; getDimensions: false; getImageDimensions: true),// sprFlake
@@ -743,7 +778,7 @@
             (FileName:  'botlevels'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
             Width: 22; Height: 15; imageWidth: 22; imageHeight: 15; saveSurf: true; critical: true; checkSum: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprBotlevels
             (FileName:  'amCleaver'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
-            Width:  64; Height: 64; imageWidth: 64; imageHeight: 64; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: false),// sprHandKnife
+            Width:  128; Height: 128; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprHandKnife
             (FileName:  'cleaver'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
             Width: 64; Height: 64; imageWidth: 64; imageHeight: 128; saveSurf: false; critical: true; checkSum: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprKnife
             (FileName:  'star'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
@@ -774,6 +809,8 @@
             Width:   0; Height:  0; imageWidth: 0; imageHeight: 0; saveSurf: true; critical: true; checkSum: true; priority: tpLow; getDimensions: true; getImageDimensions: true), // sprCustom7
             (FileName:       'custom8'; Path: ptCurrTheme;AltPath: ptGraphics; Texture: nil; Surface: nil;
             Width:   0; Height:  0; imageWidth: 0; imageHeight: 0; saveSurf: true; critical: true; checkSum: true; priority: tpLow; getDimensions: true; getImageDimensions: true), // sprCustom8
+            (FileName:      'FrozenAirMine'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  32; Height: 32; imageWidth: 32; imageHeight: 32; saveSurf: true; critical: true; checkSum: true; priority: tpHighest; getDimensions: false; getImageDimensions: true), // sprFrozenAirMine
             (FileName:      'AirMine'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
             Width:  32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpHighest; getDimensions: false; getImageDimensions: true), // sprAirMine
             (FileName:  'amAirMine'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
@@ -786,14 +823,51 @@
             Width: 256; Height:128; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: false; checkSum: false; priority: tpHigh; getDimensions: false; getImageDimensions: true),// sprCloudL
             (FileName:     'SDCloudsL'; Path: ptCurrTheme;AltPath: ptGraphics; Texture: nil; Surface: nil;
             Width: 256; Height:128; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: false; checkSum: false; priority: tpHigh; getDimensions: false; getImageDimensions: true),// sprSDCloudL
+            // TODO: Rename creeper image
             (FileName:     'Duck'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
-            Width:  32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprDuck
+            Width:  32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprCreeper
+            // TODO: Rename creeper hand image
             (FileName:    'amDuck'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
-            Width:  64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true), // sprHandDuck
+            Width:  64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true), // sprHandCreeper
             (FileName: 'amMinigun'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
-            Width:  64; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true) // sprMinigun
+            Width:  64; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true), // sprMinigun
+            (FileName:  'sliderInverted'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width: 3; Height: 17; imageWidth: 3; imageHeight: 17; saveSurf: false; critical: true; checkSum: false; priority: tpLow; getDimensions: false; getImageDimensions: false), // sprSliderInverted
+            (FileName:     'FingerBack'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  32; Height: 48; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true), // sprFingerBack
+            (FileName:     'FingerBackInv'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  32; Height: 48; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprFingerBackInv
+            (FileName:    'TargetpBack'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprTargetPBack
+            (FileName:    'TargetpBackInv'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprTargetPBackInv
+            (FileName:    'HealthHUD'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  18; Height: 18; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprHealthHud
+            (FileName:    'HealthPoisonHUD'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  18; Height: 18; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprHealthPoisonHud
+            (FileName:    'VampHUD'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  24; Height: 18; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprVampHUD
+            (FileName:    'KarmaHUD'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  18; Height: 18; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprKarmaHUD
+            (FileName:    'MedicHUD'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  18; Height: 18; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprMedicHud
+            (FileName:    'MedicPoisonHUD'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  18; Height: 18; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprMedicPoisonHud
+            (FileName:    'HaloHUD'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  22; Height: 11; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprHaloHUD
+            (FileName:    'InvulnHUD'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  18; Height: 18; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprInvulnHUD
+            (FileName: 'amPiano'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  42; Height: 42; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprAmPiano
+            (FileName:  'amLandGun'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  64; Height: 64; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true), // sprHandLandGun
+            (FileName: 'amShoryuken'; Path: ptHedgehog; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  32; Height: 32; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true),// sprFirePunch
+            (FileName: 'throughWrap'; Path: ptGraphics; AltPath: ptNone; Texture: nil; Surface: nil;
+            Width:  16; Height: 13; imageWidth: 0; imageHeight: 0; saveSurf: false; critical: true; checkSum: false; priority: tpMedium; getDimensions: false; getImageDimensions: true) // sprTroughWrap
             );
 
+
 const
     Wavez: array [TWave] of record
             Sprite: TSprite;
@@ -827,9 +901,11 @@
             PosSprite: TSprite;
             ejectX, ejectY: Longint;
             end;
+    TAmmoCounts = array[TAmmoType] of Longword;
 
 var
     Ammoz: array [TAmmoType] of TAmmozRec;
+    InitialAmmoCounts: TAmmoCounts;
 
 const
     AmmozInit: array [TAmmoType] of TAmmozRec = (
@@ -844,14 +920,14 @@
                 Pos: 0;
                 AmmoType: amNothing;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: cHiddenSlotIndex;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
-            SkipTurns: 9999;
-            PosCount: 1;
+            SkipTurns: 0;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -872,14 +948,14 @@
                 Pos: 0;
                 AmmoType: amGrenade;
                 AttackVoice: sndCover;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 1;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -900,14 +976,14 @@
                 Pos: 0;
                 AmmoType: amClusterBomb;
                 AttackVoice: sndCover;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 1;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -925,15 +1001,15 @@
                 Timer: 0;
                 Pos: 0;
                 AmmoType: amBazooka;
-                AttackVoice: sndNone;
-                Bounciness: 1000);
+                AttackVoice: sndFire;
+                Bounciness: defaultBounciness);
             Slot: 0;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0; //20;
             ejectY: -6),
@@ -946,15 +1022,17 @@
             Ammo: (Propz: ammoprop_Power or
                           ammoprop_NeedTarget or
                           ammoprop_NoTargetAfter or
+                          ammoprop_NoWrapTarget or
                           ammoprop_DontHold or
+                          ammoprop_AltUse or
                           ammoprop_NeedUpDown;
                 Count: 2;
                 NumPerTurn: 0;
                 Timer: 0;
                 Pos: 0;
                 AmmoType: amBee;
-                AttackVoice: sndNone;
-                Bounciness: 1000);
+                AttackVoice: sndFire;
+                Bounciness: defaultBounciness);
             Slot: 0;
             TimeAfterTurn: 3000;
             minAngle: 0;
@@ -980,14 +1058,14 @@
                 Pos: 0;
                 AmmoType: amShotgun;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 2;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0; //26;
             ejectY: -6),
@@ -1008,14 +1086,14 @@
                 Pos: 0;
                 AmmoType: amPickHammer;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 6;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1035,14 +1113,14 @@
                 Pos: 0;
                 AmmoType: amSkip;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 9;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1065,14 +1143,14 @@
                     Pos: 0;
                     AmmoType: amRope;
                     AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 7;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: cMaxAngle div 2;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1093,14 +1171,14 @@
                 Pos: 0;
                 AmmoType: amMine;
                 AttackVoice: sndLaugh;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 4;
             TimeAfterTurn: 5000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1117,14 +1195,14 @@
                 Pos: 0;
                 AmmoType: amDEagle;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 2;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0; //23;
             ejectY: -6),
@@ -1144,14 +1222,14 @@
                 Pos: 0;
                 AmmoType: amDynamite;
                 AttackVoice: sndLaugh;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 4;
             TimeAfterTurn: 5000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1170,14 +1248,14 @@
                 Pos: 0;
                 AmmoType: amFirePunch;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 3;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1194,14 +1272,14 @@
                 Pos: 0;
                 AmmoType: amWhip;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 3;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1219,14 +1297,14 @@
                 Pos: 0;
                 AmmoType: amBaseballBat;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 3;
             TimeAfterTurn: 5000;
             minAngle: 0;
             maxAngle: cMaxAngle div 2;
             isDamaging: true;
             SkipTurns: 2;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1243,6 +1321,7 @@
                           ammoprop_DontHold or
                           ammoprop_Utility or
                           ammoprop_AltAttack or
+                          ammoprop_ShowSelIcon or
                           ammoprop_NeedUpDown;
                 Count: 2;
                 NumPerTurn: 0;
@@ -1250,14 +1329,14 @@
                 Pos: 0;
                 AmmoType: amParachute;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 7;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1277,8 +1356,8 @@
                 Timer: 0;
                 Pos: 0;
                 AmmoType: amAirAttack;
-                AttackVoice: sndIncoming;
-                Bounciness: 1000);
+                AttackVoice: sndNone; // handled in doStepAirAttack
+                Bounciness: defaultBounciness);
             Slot: 5;
             TimeAfterTurn: 0;
             minAngle: 0;
@@ -1305,8 +1384,8 @@
                 Timer: 0;
                 Pos: 0;
                 AmmoType: amMineStrike;
-                AttackVoice: sndIncoming;
-                Bounciness: 1000);
+                AttackVoice: sndNone; // handled in doStepAirAttack
+                Bounciness: defaultBounciness);
             Slot: 5;
             TimeAfterTurn: 0;
             minAngle: 0;
@@ -1332,14 +1411,14 @@
                 Pos: 0;
                 AmmoType: amBlowTorch;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 6;
             TimeAfterTurn: 3000;
             minAngle: 804;
             maxAngle: 1327;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1360,7 +1439,7 @@
                     Pos: 0;
                     AmmoType: amGirder;
                     AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 6;
             TimeAfterTurn: 3000;
             minAngle: 0;
@@ -1381,6 +1460,7 @@
                           ammoprop_NoCrosshair or
                           ammoprop_NeedTarget or
                           ammoprop_AttackingPut or
+                          ammoprop_AttackInMove or
                           ammoprop_Utility or
                           ammoprop_DontHold;
                 Count: 2;
@@ -1389,7 +1469,7 @@
                 Pos: 0;
                 AmmoType: amTeleport;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 7;
             TimeAfterTurn: 0;
             minAngle: 0;
@@ -1410,6 +1490,7 @@
                           ammoprop_ForwMsgs or
                           ammoprop_NoCrosshair or
                           ammoprop_Utility or
+                          ammoprop_ShowSelIcon or
                           ammoprop_DontHold;
                     Count: 3;
                     NumPerTurn: 0;
@@ -1417,14 +1498,14 @@
                     Pos: 0;
                     AmmoType: amSwitch;
                     AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 9;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1441,14 +1522,14 @@
                 Pos: 0;
                 AmmoType: amMortar;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 0;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0; //20;
             ejectY: -6),
@@ -1469,14 +1550,14 @@
                 Pos: 0;
                 AmmoType: amKamikaze;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 3;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1496,14 +1577,14 @@
                 Pos: 0;
                 AmmoType: amCake;
                 AttackVoice: sndLaugh;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 4;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 4;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1522,14 +1603,14 @@
                 Pos: 0;
                 AmmoType: amSeduction;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 3;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1549,14 +1630,14 @@
                 Pos: 0;
                 AmmoType: amWatermelon;
                 AttackVoice: sndMelon;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 1;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1574,15 +1655,15 @@
                 Timer: 5000;
                 Pos: 0;
                 AmmoType: amHellishBomb;
-                AttackVoice: sndNone;
-                Bounciness: 1000);
+                AttackVoice: sndWatchThis;
+                Bounciness: defaultBounciness);
             Slot: 1;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1602,8 +1683,8 @@
                 Timer: 0;
                 Pos: 0;
                 AmmoType: amNapalm;
-                AttackVoice: sndIncoming;
-                Bounciness: 1000);
+                AttackVoice: sndNone; // handled in doStepAirAttack
+                Bounciness: defaultBounciness);
             Slot: 5;
             TimeAfterTurn: 0;
             minAngle: 0;
@@ -1628,15 +1709,15 @@
                 Timer: 0;
                 Pos: 0;
                 AmmoType: amDrill;
-                AttackVoice: sndNone;
-                Bounciness: 1000);
+                AttackVoice: sndFire;
+                Bounciness: defaultBounciness);
             Slot: 0;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprDrill;
             ejectX: 0; //20;
             ejectY: -6),
@@ -1655,14 +1736,14 @@
                 Pos: 0;
                 AmmoType: amBallgun;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 4;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0; //20;
             ejectY: -3),
@@ -1682,14 +1763,14 @@
                 Pos: 0;
                 AmmoType: amRCPlane;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 4;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 4;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1703,6 +1784,7 @@
                           ammoprop_NoCrosshair or
                           ammoprop_DontHold or
                           ammoprop_AltUse or
+                          ammoprop_ShowSelIcon or
                           ammoprop_Utility or
                           ammoprop_Effect;
                     Count: 1;
@@ -1711,14 +1793,14 @@
                     Pos: 0;
                     AmmoType: amLowGravity;
                     AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 9;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1732,6 +1814,7 @@
                           ammoprop_NoCrosshair or
                           ammoprop_DontHold or
                           ammoprop_AltUse or
+                          ammoprop_ShowSelIcon or
                           ammoprop_Utility or
                           ammoprop_Effect;
                     Count: 1;
@@ -1740,14 +1823,14 @@
                     Pos: 0;
                     AmmoType: amExtraDamage;
                     AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 9;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1761,6 +1844,7 @@
                           ammoprop_NoCrosshair or
                           ammoprop_DontHold or
                           ammoprop_AltUse or
+                          ammoprop_ShowSelIcon or
                           ammoprop_Utility or
                           ammoprop_Effect;
                     Count: 1;
@@ -1769,14 +1853,14 @@
                     Pos: 0;
                     AmmoType: amInvulnerable;
                     AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 8;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1790,6 +1874,7 @@
                           ammoprop_NoCrosshair or
                           ammoprop_DontHold or
                           ammoprop_AltUse or
+                          ammoprop_ShowSelIcon or
                           ammoprop_Utility or
                           ammoprop_Effect;
                     Count: 1;
@@ -1798,14 +1883,14 @@
                     Pos: 0;
                     AmmoType: amExtraTime;
                     AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 9;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1819,6 +1904,7 @@
                           ammoprop_NoCrosshair or
                           ammoprop_DontHold or
                           ammoprop_AltUse or
+                          ammoprop_ShowSelIcon or
                           ammoprop_Utility or
                           ammoprop_NeedUpDown or
                           ammoprop_Effect;
@@ -1828,14 +1914,14 @@
                     Pos: 0;
                     AmmoType: amLaserSight;
                     AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 8;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1857,14 +1943,14 @@
                     Pos: 0;
                     AmmoType: amVampiric;
                     AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 8;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1884,14 +1970,14 @@
                 Pos: 0;
                 AmmoType: amSniperRifle;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 2;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0; //40;
             ejectY: -5),
@@ -1907,6 +1993,7 @@
                           ammoprop_DontHold or
                           ammoprop_Utility or
                           ammoprop_NeedUpDown or
+                          ammoprop_ShowSelIcon or
                           ammoprop_AltAttack;
                 Count: 1;
                 NumPerTurn: 0;
@@ -1914,14 +2001,14 @@
                 Pos: 0;
                 AmmoType: amJetpack;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 7;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1939,15 +2026,15 @@
                 Timer: 3000;
                 Pos: 0;
                 AmmoType: amMolotov;
-                AttackVoice: sndNone;
-                Bounciness: 1000);
+                AttackVoice: sndWatchThis;
+                Bounciness: defaultBounciness);
             Slot: 1;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1960,6 +2047,7 @@
             Ammo: (Propz: ammoprop_ForwMsgs or
                           ammoprop_NoCrosshair or
                           ammoprop_NeedUpDown or
+                          ammoprop_ShowSelIcon or
                           ammoprop_DontHold;
                 Count: 1;
                 NumPerTurn: 0;
@@ -1967,14 +2055,14 @@
                 Pos: 0;
                 AmmoType: amBirdy;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 7;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -1995,14 +2083,14 @@
                 Pos: 0;
                 AmmoType: amPortalGun;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 7;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: -5; //29;
             ejectY: -7),
@@ -2014,7 +2102,7 @@
             NumberInCase: 1;
             Ammo: (Propz: ammoprop_NoCrosshair or
                             ammoprop_NeedTarget or
-                            ammoprop_NoTargetAfter or
+                            // NoTargetAfter is handled manually in doStepPiano
                             ammoprop_AttackingPut or
                             ammoprop_DontHold or
                             ammoprop_NotBorder or
@@ -2024,8 +2112,8 @@
                 Timer: 0;
                 Pos: 0;
                 AmmoType: amPiano;
-                AttackVoice: sndIncoming;
-                Bounciness: 1000);
+                AttackVoice: sndNone; // handled in doStepPiano
+                Bounciness: defaultBounciness);
             Slot: 5;
             TimeAfterTurn: 0;
             minAngle: 0;
@@ -2033,7 +2121,7 @@
             isDamaging: true;
             SkipTurns: 7;
             PosCount: 1;
-            PosSprite: sprWater;
+            PosSprite: sprAmPiano;
             ejectX: 0;
             ejectY: 0),
 
@@ -2053,14 +2141,14 @@
                 Pos: 0;
                 AmmoType: amGasBomb;
                 AttackVoice: sndCover;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 1;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -2078,14 +2166,14 @@
                 Pos: 0;
                 AmmoType: amSineGun;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 2;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -2104,14 +2192,14 @@
                 Pos: 0;
                 AmmoType: amFlamethrower;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
-            Slot: 2;
+                Bounciness: defaultBounciness);
+            Slot: 6;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0; //20;
             ejectY: -3),
@@ -2130,14 +2218,14 @@
                 Pos: 0;
                 AmmoType: amSMine;
                 AttackVoice: sndLaugh;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 4;
             TimeAfterTurn: 5000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -2154,14 +2242,14 @@
                 Pos: 0;
                 AmmoType: amHammer;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 3;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -2173,21 +2261,22 @@
             NumberInCase: 1;
             Ammo: (Propz: ammoprop_NoCrosshair or
                           ammoprop_Utility or
-                          ammoprop_NoRoundEnd;
+                          ammoprop_NoRoundEnd or
+                          ammoprop_DoesntStopTimerWhileAttacking;
                 Count: 1;
                 NumPerTurn: 0;
                 Timer: 0;
                 Pos: 0;
                 AmmoType: amResurrector;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 8;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -2208,8 +2297,8 @@
                 Timer: 5000;
                 Pos: 0;
                 AmmoType: amDrillStrike;
-                AttackVoice: sndIncoming;
-                Bounciness: 1000);
+                AttackVoice: sndNone; // handled in doStepAirAttack
+                Bounciness: defaultBounciness);
             Slot: 5;
             TimeAfterTurn: 0;
             minAngle: 0;
@@ -2236,14 +2325,14 @@
                 Pos: 0;
                 AmmoType: amSnowball;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 0;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -2256,6 +2345,7 @@
             Ammo: (Propz: ammoprop_ForwMsgs or
                           ammoprop_NoCrosshair or
                           ammoprop_Utility or
+                          ammoprop_ShowSelIcon or
                           ammoprop_DontHold or
                           ammoprop_ForceTurnEnd;
                 Count: 2;
@@ -2264,7 +2354,7 @@
                 Pos: 0;
                 AmmoType: amTardis;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 8;
             TimeAfterTurn: 0;
             minAngle: 0;
@@ -2276,35 +2366,6 @@
             ejectX: 0;
             ejectY: 0),
 
-// Structure
-{
-            (NameId: sidStructure;
-            NameTex: nil;
-            Probability: 0;
-            NumberInCase: 1;
-            Ammo: (Propz: ammoprop_ForwMsgs or
-                          ammoprop_NoCrosshair or
-                          ammoprop_Utility or
-                          ammoprop_DontHold;
-                Count: 1;
-                NumPerTurn: 0;
-                Timer: 0;
-                Pos: 0;
-                AmmoType: amStructure;
-                AttackVoice: sndNone;
-                Bounciness: 1000);
-            Slot: 6;
-            TimeAfterTurn: 0;
-            minAngle: 0;
-            maxAngle: 0;
-            isDamaging: false;
-            SkipTurns: 0;
-            PosCount: 1;
-            PosSprite: sprWater;
-            ejectX: 0;
-            ejectY: 0),
-}
-
 // Land Gun
             (NameId: sidLandGun;
             NameTex: nil;
@@ -2319,14 +2380,14 @@
                 Pos: 0;
                 AmmoType: amLandGun;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 6;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0; //20;
             ejectY: -3),
@@ -2344,14 +2405,14 @@
                 Pos: 0;
                 AmmoType: amIceGun;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 2;
             TimeAfterTurn: 0;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: false;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0; //20;
             ejectY: -3),
@@ -2368,15 +2429,15 @@
                 Timer: 0;
                 Pos: 0;
                 AmmoType: amKnife;
-                AttackVoice: sndNone;
-                Bounciness: 1000);
-            Slot: 6;
+                AttackVoice: sndWatchThis;
+                Bounciness: defaultBounciness);
+            Slot: 0;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
@@ -2396,7 +2457,7 @@
                     Pos: 0;
                     AmmoType: amRubber;
                     AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 6;
             TimeAfterTurn: 3000;
             minAngle: 0;
@@ -2421,19 +2482,19 @@
                 Pos: 0;
                 AmmoType: amAirMine;
                 AttackVoice: sndLaugh;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 5;
             TimeAfterTurn: 5000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0;
             ejectY: 0),
-// Rubber duck
-            (NameId: sidDuck;
+// Creeper
+            (NameId: sidCreeper;
             NameTex: nil;
             Probability: 100;
             NumberInCase: 1;
@@ -2445,16 +2506,18 @@
                 NumPerTurn: 0;
                 Timer: 15000;
                 Pos: 0;
-                AmmoType: amDuck;
+                AmmoType: amCreeper;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
-            Slot: 0;
+                Bounciness: defaultBounciness);
+            // Slot chosen to prevent ammo column overflow
+            // TODO: Change slot when creeper is finished
+            Slot: 8;
             TimeAfterTurn: 3000;
             minAngle: 0;
             maxAngle: 0;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 15;
             ejectY: -7),
@@ -2470,14 +2533,14 @@
                 Pos: 0;
                 AmmoType: amMinigun;
                 AttackVoice: sndNone;
-                Bounciness: 1000);
+                Bounciness: defaultBounciness);
             Slot: 2;
             TimeAfterTurn: 3000;
             minAngle: cMaxAngle div 6;
             maxAngle: 5 * cMaxAngle div 6;
             isDamaging: true;
             SkipTurns: 0;
-            PosCount: 1;
+            PosCount: 0;
             PosSprite: sprWater;
             ejectX: 0; //23;
             ejectY: 0) //-6;
@@ -2489,7 +2552,8 @@
     LandDirty: TDirtyTag;
     hasBorder: boolean;
     hasGirders: boolean;
-    playHeight, playWidth, leftX, rightX, topY, MaxHedgehogs: Longword;  // idea is that a template can specify height/width.  Or, a map, a height/width by the dimensions of the image.  If the map has pixels near top of image, it triggers border.
+    playHeight, playWidth, leftX, rightX, topY: LongInt;  // idea is that a template can specify height/width.  Or, a map, a height/width by the dimensions of the image.  If the map has pixels near top of image, it triggers border.
+	MaxHedgehogs: LongWord;
     LandBackSurface: PSDL_Surface;
     CurAmmoGear: PGear;
     lastGearByUID: PGear;
@@ -2503,18 +2567,19 @@
     SpeechType: Longword;
     SpeechText: shortstring;
     PlacingHogs: boolean; // a convenience flag to indicate placement of hogs is still in progress
+    PlacingKings: boolean; // a convenience flag to indicate placement of kings in King Mode is still in progress
     StepSoundTimer: LongInt;
     StepSoundChannel: LongInt;
 
     CurrentTeam: PTeam;
     PreviousTeam: PTeam;
+    MissionTeam: PTeam;
     CurrentHedgehog: PHedgehog;
     TeamsArray: array[0..Pred(cMaxTeams)] of PTeam;
     TeamsCount: Longword; // number of teams on game start
     VisibleTeamsCount: Longword; // number of teams visible in team bar
     ClansArray, SpawnClansArray: TClansArray;
     ClansCount: Longword;
-    LocalClan: LongInt;  // last non-bot, non-extdriven clan
     LocalTeam: LongInt;  // last non-bot, non-extdriven clan first team
     LocalAmmo: LongInt;  // last non-bot, non-extdriven clan's first team's ammo index, updated to next upcoming hog for per-hog-ammo
     CurMinAngle, CurMaxAngle: Longword;
@@ -2584,6 +2649,8 @@
     aTexCoord: GLint;
     aColor: GLint;
 
+    lDecimalSeparator: Char;
+
 var trammo:  array[TAmmoStrId] of ansistring;   // name of the weapon
     trammoc: array[TAmmoStrId] of ansistring;   // caption of the weapon
     trammod: array[TAmmoStrId] of ansistring;   // description of the weapon
@@ -2591,8 +2658,10 @@
     trluaammoc: array[TAmmoStrId] of ansistring; // caption of the weapon (Lua overwrite)
     trluaammod: array[TAmmoStrId] of ansistring;  // description of the weapon (Lua overwrite)
     trluaammoa: array[TAmmoStrId] of ansistring; // description appendix of the weapon (Lua only)
+    trluaammoe: array[TAmmoStrId] of boolean;   // whether to render extra text (Lua overwrite)
     trmsg:   array[TMsgStrId]  of ansistring;   // message of the event
     trgoal:  array[TGoalStrId] of ansistring;   // message of the goal
+    trcmd:   array[TCmdHelpStrId] of ansistring; // chat command help
     cTestLua : Boolean;
 
 procedure preInitModule;
@@ -2614,9 +2683,10 @@
 
     cShowFPS        := false;
     cAltDamage      := false;
+    cHolidaySilliness := true;
     cTimerInterval  := 8;
     cReducedQuality := rqNone;
-    cLocaleFName    := 'en.txt';
+    cLanguageFName  := 'en.txt';
     cFullScreen     := false;
 
     UserPathPrefix  := '';
@@ -2632,6 +2702,22 @@
     cScriptParam    := '';
     cTestLua        := False;
 
+    UserZoom        := cDefaultZoomLevel;
+    zoom            := cDefaultZoomLevel;
+    ZoomValue       := cDefaultZoomLevel;
+
+{$IFDEF MOBILE}
+    cMaxZoomLevel   := 0.5;
+    cMinZoomLevel   := 3.5;
+    cZoomDelta      := 0.20;
+    cZoomDeltaSmall := 0.10;
+{$ELSE}
+    cMaxZoomLevel   := 1.0;
+    cMinZoomLevel   := 3.0;
+    cZoomDelta      := 0.25;
+    cZoomDeltaSmall := 0.125;
+{$ENDIF}
+
 {$IFDEF USE_VIDEO_RECORDING}
     RecPrefix          := '';
     cAVFormat          := '';
@@ -2660,6 +2746,7 @@
 var s: shortstring;
     i: integer;
     t: TSound;
+    a: TAmmoStrId;
 begin
     // init LastVoice
     LastVoice.snd:= sndNone;
@@ -2672,8 +2759,8 @@
     Move(AmmozInit, Ammoz, sizeof(Ammoz));
 
 
-    cLocale:= cLocaleFName;
-    SplitByChar(cLocale, s, '.');
+    cLanguage:= cLanguageFName;
+    SplitByChar(cLanguage, s, '.');
 
     cFlattenFlakes      := false;
     cFlattenClouds      := false;
@@ -2723,6 +2810,19 @@
 
     WaterOpacity:= $80;
 
+    // default clan colors
+    // always keep in sync with QTfrontend/hwconsts.h
+
+    ClanColorArray[0] := $ffff0204;
+    ClanColorArray[1] := $ff4980c1;
+    ClanColorArray[2] := $ff1de6ba;
+    ClanColorArray[3] := $ffb541ef;
+    ClanColorArray[4] := $ffe55bb0;
+    ClanColorArray[5] := $ff20bf00;
+    ClanColorArray[6] := $fffe8b0e;
+    ClanColorArray[7] := $ff8f5902;
+    ClanColorArray[8] := $ffffff01;
+
     // default sudden death water
 
     // deep water
@@ -2773,27 +2873,22 @@
     cDamageModifier         := _1;
     TargetPoint             := cTargetPointRef;
 
-{$IFDEF MOBILE}
-    cMaxZoomLevel:= 0.5;
-    cMinZoomLevel:= 3.5;
-    cZoomDelta:= 0.20;
-{$ELSE}
-    cMaxZoomLevel:= 1.0;
-    cMinZoomLevel:= 3.0;
-    cZoomDelta:= 0.25;
-    {$ENDIF}
-
     aVertex:= 0;
     aTexCoord:= 1;
     aColor:= 2;
 
+    lDecimalSeparator       := '.';
+
 
     cMinMaxZoomLevelDelta:= cMaxZoomLevel - cMinZoomLevel;
 
+    cDemoClockFPSOffsetY := 0;
+
     // int, longint longword and byte
     CursorMovementX     := 0;
     CursorMovementY     := 0;
     GameTicks           := 0;
+    OuchTauntTimer      := 0;
     CheckSum            := 0;
     cWaterLine          := LAND_HEIGHT;
     cGearScrEdgesDist   := 240;
@@ -2809,12 +2904,16 @@
     TurnClockActive     := true;
     TagTurnTimeLeft     := 0;
     cSuddenDTurns       := 15;
+    LastSuddenDWarn     := -2;
+    cInitHealth         := 100;
     cDamagePercent      := 100;
     cRopePercent        := 100;
+    cRopeNodeStep       := 4;
+    cRopeLayers         := 1;
     cGetAwayTime        := 100;
     cMineDudPercent     := 0;
     cTemplateFilter     := 0;
-    cFeatureSize        := 50;
+    cFeatureSize        := 12;
     cMapGen             := mgRandom;
     cHedgehogTurnTime   := 45000;
     cMinesTime          := 3000;
@@ -2831,6 +2930,7 @@
     RealTicks       := 0;
     AttackBar       := 0; // 0 - none, 1 - just bar at the right-down corner, 2 - from weapon
     cCaseFactor     := 5;  {0..9}
+    cMaxCaseDrops   := 5;
     cLandMines      := 4;
     cAirMines       := 0;
     cExplosives     := 2;
@@ -2854,18 +2954,25 @@
     flagDumpLand    := false;
     bBetweenTurns   := false;
     bWaterRising    := false;
+    bDuringWaterRise:= false;
     isCursorVisible := false;
     isInLag         := false;
     isPaused        := false;
     isInMultiShoot  := false;
     isSpeed         := false;
     isAFK           := false;
+    isShowMission   := false;
+    isShowGearInfo  := false;
+    isForceMission  := false;
     SpeedStart      := 0;
     fastUntilLag    := false;
     fastScrolling   := false;
     autoCameraOn    := true;
     cSeed           := '';
+    cIsSoundEnabled := false;
     cVolumeDelta    := 0;
+    cVolumeUpKey    := false;
+    cVolumeDownKey  := false;
     cMuteToggle     := false;
     cHasFocus       := true;
     cInactDelay     := 100;
@@ -2929,9 +3036,14 @@
     LuaEndTurnRequested:= false;
     LuaNoEndTurnTaunts:= false;
 
+    LuaCmdUsed:= false;
+
     for t:= Low(TSound) to High(TSound) do
         MaskedSounds[t]:= false;
 
+    for a:= Low(TAmmoStrId) to High(TAmmoStrId) do
+        trluaammoe[a]:= true;
+
     UIDisplay:= uiAll;
     LocalMessage:= 0;
 
@@ -2946,6 +3058,7 @@
     GearsList:= nil;
     CurrentTeam:= nil;
     PreviousTeam:= nil;
+    MissionTeam:= nil;
     CurrentHedgehog:= nil;
     FollowGear:= nil;
     lastVisualGearByUID:= nil;