merge hedgeroid
authorXeli
Fri, 01 Jul 2011 08:46:47 +0200
branchhedgeroid
changeset 5385 a864a0aeed96
parent 5383 cb217271f344 (current diff)
parent 5366 bfdd925e89a5 (diff)
child 5387 e67241f4e59a
merge
hedgewars/uCommandHandlers.pas
--- a/QTfrontend/CMakeLists.txt	Wed Jun 29 18:09:24 2011 +0200
+++ b/QTfrontend/CMakeLists.txt	Fri Jul 01 08:46:47 2011 +0200
@@ -161,7 +161,6 @@
     pagedrawmap.h
     pagecampaign.h
     pagenetgame.h
-    pageeditteam.h
     pageroomslist.h
     pagegamestats.h
     pageadmin.h
--- a/QTfrontend/gamecfgwidget.cpp	Wed Jun 29 18:09:24 2011 +0200
+++ b/QTfrontend/gamecfgwidget.cpp	Fri Jul 01 08:46:47 2011 +0200
@@ -229,6 +229,20 @@
     QList<QByteArray> bcfg;
     int mapgen = pMapContainer->get_mapgen();
 
+    QString currentMap = pMapContainer->getCurrentMap();
+    if (currentMap.size() > 0)
+    {
+        bcfg << QString("emap " + currentMap).toUtf8();
+        if(pMapContainer->getCurrentIsMission())
+            bcfg << QString("escript Maps/%1/map.lua").arg(currentMap).toUtf8();
+    }
+    bcfg << QString("etheme " + pMapContainer->getCurrentTheme()).toUtf8();
+
+    if (Scripts->currentIndex() > 0)
+    {
+        bcfg << QString("escript Scripts/Multiplayer/%1.lua").arg(Scripts->itemData(Scripts->currentIndex()).toList()[0].toString()).toUtf8();
+    }
+
     bcfg << QString("eseed " + pMapContainer->getCurrentSeed()).toUtf8();
     bcfg << QString("e$gmflags %1").arg(getGameFlags()).toUtf8();
     bcfg << QString("e$damagepct %1").arg(schemeData(25).toInt()).toUtf8();
@@ -270,20 +284,6 @@
         default: ;
     }
 
-    QString currentMap = pMapContainer->getCurrentMap();
-    if (currentMap.size() > 0)
-    {
-        bcfg << QString("emap " + currentMap).toUtf8();
-        if(pMapContainer->getCurrentIsMission())
-            bcfg << QString("escript Maps/%1/map.lua").arg(currentMap).toUtf8();
-    }
-    bcfg << QString("etheme " + pMapContainer->getCurrentTheme()).toUtf8();
-
-    if (Scripts->currentIndex() > 0)
-    {
-        bcfg << QString("escript Scripts/Multiplayer/%1.lua").arg(Scripts->itemData(Scripts->currentIndex()).toList()[0].toString()).toUtf8();
-    }
-
     QByteArray result;
 
     foreach(QByteArray ba, bcfg)
--- a/hedgewars/GSHandlers.inc	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/GSHandlers.inc	Fri Jul 01 08:46:47 2011 +0200
@@ -605,7 +605,8 @@
     begin
     with Gear^ do
         begin
-        X:= X + cWindSpeed * 1600 + dX;
+        State:= State and not gstInvisible;
+        X:= X + cWindSpeed * 3200 + dX;
         Y:= Y + dY + cGravity * vobFallSpeed * 8;  // using same value as flakes to try and get similar results
         xx:= hwRound(X);
         yy:= hwRound(Y);
@@ -625,9 +626,9 @@
             end;
     // move back to cloud layer
         if yy > cWaterLine then move:= true
-        else if ((yy and LAND_HEIGHT_MASK) <> 0) or ((xx and LAND_WIDTH_MASK) <> 0) then move:=true
+        else if ((yy and LAND_HEIGHT_MASK) <> 0) or (xx > LAND_WIDTH + 512) or (xx < -512) then move:=true
         // Solid pixel encountered
-        else if (Land[yy, xx] <> 0) then
+        else if ((xx and LAND_WIDTH_MASK) = 0) and (Land[yy, xx] <> 0) then
             begin
             // If there's room below keep falling
             if (((yy-1) and LAND_HEIGHT_MASK) = 0) and (Land[yy-1, xx] = 0) then
@@ -2565,7 +2566,6 @@
         HHGear := Gear^.Hedgehog^.Gear;
         Msg := Gear^.Message and not gmSwitch;
         DeleteGear(Gear);
-        OnUsedAmmo(HHGear^.Hedgehog^);
         ApplyAmmoChanges(HHGear^.Hedgehog^);
 
         HHGear := CurrentHedgehog^.Gear;
@@ -2614,6 +2614,7 @@
     Gear^.doStep := @doStepSwitcherWork;
 
     HHGear := Gear^.Hedgehog^.Gear;
+    OnUsedAmmo(HHGear^.Hedgehog^);
     with HHGear^ do
     begin
         State := State and not gstAttacking;
@@ -4534,7 +4535,7 @@
     Gear^.Y:= Gear^.Y + Gear^.dY;
     Gear^.dX := Gear^.dX + cWindSpeed / 4;
     Gear^.dY := Gear^.dY + cGravity / 100;
-    if (GameTicks mod 250) = 0 then
+    if (GameTicks and $FF) = 0 then
         doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 20, Gear^.Hedgehog, EXPLDontDraw or EXPLNoGfx or EXPLNoDamage or EXPLDoNotTouchAny or EXPLPoisoned);
     AllInactive:= false;
 end;
--- a/hedgewars/HHHandlers.inc	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/HHHandlers.inc	Fri Jul 01 08:46:47 2011 +0200
@@ -533,7 +533,13 @@
 begin
 Gear^.Message:= gmDestroy;
 PlaySound(sndShotgunReload);
-if (Gear^.Pos and posCaseTrap) <> 0 then doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 30, HH^.Hedgehog, EXPLAutoSound)
+if (Gear^.Pos and posCaseExplode) <> 0 then
+    if (Gear^.Pos and posCasePoison) <> 0 then
+        doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound + EXPLPoisoned)
+    else
+        doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound)
+else if (Gear^.Pos and posCasePoison) <> 0 then
+    doMakeExplosion(hwRound(Gear^.X), hwRound(Gear^.Y), 25, HH^.Hedgehog, EXPLAutoSound + EXPLPoisoned + EXPLNoDamage)
 else
 case Gear^.Pos of
        posCaseUtility,
--- a/hedgewars/VGSHandlers.inc	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/VGSHandlers.inc	Fri Jul 01 08:46:47 2011 +0200
@@ -46,7 +46,7 @@
         inc(Frame);
         if Frame = vobSDFramesCount then Frame:= 0
         end;
-    X:= X + (cWindSpeedf * 600 + dX + tdX) * Steps;
+    X:= X + (cWindSpeedf * 400 + dX + tdX) * Steps;
     if SuddenDeathDmg then
         Y:= Y + (dY + tdY + cGravityf * vobSDFallSpeed) * Steps
     else
@@ -607,6 +607,9 @@
 (*
 FIXME - This block desyncs due to the way WorldDx is important for various things network related.
 One possible solution is, instead of using WorldDx, to use straight gl/SDL calls to jitter the screen a bit.
+
+// a comment by unC0Rr: instead of changing WorldDx shake cursor coordinates, that should be safe
+
 if (Gear^.Timer and 5) = 0 then
     begin
     maxMovement := max(1, 13 - ((Gear^.Timer * 15) div 250));
@@ -688,3 +691,20 @@
                 end
             end
 end;
+
+////////////////////////////////////////////////////////////////////////////////
+procedure doStepSmoothWindBar(Gear: PVisualGear; Steps: Longword);
+begin
+    inc(Gear^.Timer, Steps);
+    
+    while Gear^.Timer >= 10 do
+        begin
+        dec(Gear^.Timer, 10);
+        if WindBarWidth < Gear^.Tag then inc(WindBarWidth)
+        else if WindBarWidth > Gear^.Tag then dec(WindBarWidth);
+        end;
+        
+if WindBarWidth = Gear^.Tag then 
+    DeleteVisualGear(Gear)
+end;
+
--- a/hedgewars/uAmmos.pas	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/uAmmos.pas	Fri Jul 01 08:46:47 2011 +0200
@@ -123,13 +123,13 @@
         if ((GameFlags and gfPlaceHog) <> 0) and
             (a <> amTeleport) and (a <> amSkip) and
             (Ammoz[a].SkipTurns < 10000) then inc(Ammoz[a].SkipTurns,10000);
-	if ((GameFlags and gfPlaceHog) <> 0) and (a = amTeleport) then ammos[a]:= AMMO_INFINITE
+    if ((GameFlags and gfPlaceHog) <> 0) and (a = amTeleport) then ammos[a]:= AMMO_INFINITE
         end 
     else ammos[a]:= AMMO_INFINITE;
     if ((GameFlags and gfPlaceHog) <> 0) and (a = amTeleport) then 
-    	InitialCounts[Pred(StoreCnt)][a]:= cnt
+        InitialCounts[Pred(StoreCnt)][a]:= cnt
     else
-    	InitialCounts[Pred(StoreCnt)][a]:= ammos[a];
+        InitialCounts[Pred(StoreCnt)][a]:= ammos[a];
     end;
 FillAmmoStore(StoresList[Pred(StoreCnt)], ammos)
 end;
@@ -208,15 +208,12 @@
 
 FillAmmoStore(hhammo, ammos);
 CurWeapon:= GetAmmoEntry(Hedgehog);
-with Hedgehog do
-    begin
-    with CurWeapon^ do
+with Hedgehog, CurWeapon^ do
         if Count = 0 then
             begin
             PackAmmo(Ammo, Ammoz[AmmoType].Slot);
             CurAmmoType:= amNothing
             end
-    end
 end;
 
 procedure PackAmmo(Ammo: PHHAmmo; Slot: LongInt);
--- a/hedgewars/uCommandHandlers.pas	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/uCommandHandlers.pas	Fri Jul 01 08:46:47 2011 +0200
@@ -445,7 +445,7 @@
 
 procedure chSetMap(var s: shortstring);
 begin
-if isDeveloperMode then
+if isDeveloperMode and (s <> '') then
 begin
 UserPathz[ptMapCurrent]:= UserPathz[ptMaps] + '/' + s;
 Pathz[ptMapCurrent]:= Pathz[ptMaps] + '/' + s;
--- a/hedgewars/uCommands.pas	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/uCommands.pas	Fri Jul 01 08:46:47 2011 +0200
@@ -33,7 +33,7 @@
 procedure StopMessages(Message: Longword);
 
 implementation
-uses Types, uConsts, uVariables, uConsole, uUtils, uDebug;
+uses Types, uConsts, uVariables, uConsole, uUtils, uDebug, uScript;
 
 type  PVariable = ^TVariable;
       TVariable = record
@@ -68,7 +68,7 @@
 
 procedure ParseCommand(CmdStr: shortstring; TrustedSource: boolean);
 var ii: LongInt;
-    s: shortstring;
+    s, i, o: shortstring;
     t: PVariable;
     c: char;
 begin
@@ -85,6 +85,8 @@
       if t^.Name = CmdStr then
          begin
          if TrustedSource or t^.Trusted then
+            begin
+            if (c <> '$') or (s[0] <> #0) then s:= ParseCommandOverride(CmdStr, s);
             case t^.VType of
               vtCommand: if c='/' then
                          begin
@@ -94,8 +96,12 @@
                          if s[0]=#0 then
                             begin
                             str(PLongInt(t^.Handler)^, s);
-                            WriteLnToConsole('$' + CmdStr + ' is "' + s + '"');
-                            end else val(s, PLongInt(t^.Handler)^);
+                            i:= inttostr(PLongInt(t^.Handler)^);
+                            o:= ParseCommandOverride(CmdStr, i);
+                            if i <> o then val(o, PLongInt(t^.Handler)^) 
+                            else WriteLnToConsole('$' + CmdStr + ' is "' + s + '"');
+                            end 
+                         else val(s, PLongInt(t^.Handler)^);
               vthwFloat: if c='$' then
                          if s[0]=#0 then
                             begin
@@ -106,13 +112,23 @@
                          if s[0]=#0 then
                             begin
                             str(ord(boolean(t^.Handler^)), s);
-                            WriteLnToConsole('$' + CmdStr + ' is "' + s + '"');
-                            end else
+                            if boolean(t^.Handler^) then i:= '1'
+                            else i:= '0';
+                            o:= ParseCommandOverride(CmdStr, i);
+                            if i <> o then 
+                                begin
+                                val(o, ii);
+                                boolean(t^.Handler^):= not (ii = 0)
+                                end
+                            else WriteLnToConsole('$' + CmdStr + ' is "' + s + '"');
+                            end 
+                         else
                             begin
                             val(s, ii);
                             boolean(t^.Handler^):= not (ii = 0)
                             end;
               end;
+              end;
          exit
          end else t:= t^.Next
       end;
--- a/hedgewars/uConsts.pas	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/uConsts.pas	Fri Jul 01 08:46:47 2011 +0200
@@ -209,6 +209,7 @@
     gstNotKickable    = $00040000;
     gstLoser          = $00080000;
     gstHHGone         = $00100000;
+    gstInvisible      = $00200000;
 
     gmLeft   = $00000001;
     gmRight  = $00000002;
@@ -260,7 +261,8 @@
     posCaseHealth  = $00000002;
     posCaseUtility = $00000004;
     posCaseDummy   = $00000008;
-    posCaseTrap    = $00000010;
+    posCaseExplode = $00000010;
+    posCasePoison  = $00000020;
 
     NoPointX = Low(LongInt);
     cTargetPointRef : TPoint = (X: NoPointX; Y: 0);
--- a/hedgewars/uGame.pas	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/uGame.pas	Fri Jul 01 08:46:47 2011 +0200
@@ -75,6 +75,7 @@
                         if isSoundEnabled then playMusic;
                         GameType:= gmtLocal;
                         AddVisualGear(0, 0, vgtTeamHealthSorter);
+                        AddVisualGear(0, 0, vgtSmoothWindBar);
                         {$IFDEF IPHONEOS}InitIPC;{$ENDIF}
                         uMobile.SaveFinished();
                         end;
--- a/hedgewars/uGears.pas	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/uGears.pas	Fri Jul 01 08:46:47 2011 +0200
@@ -39,7 +39,7 @@
 procedure freeModule;
 function  AddGear(X, Y: LongInt; Kind: TGearType; State: Longword; dX, dY: hwFloat; Timer: LongWord): PGear;
 function  SpawnCustomCrateAt(x, y: LongInt; crate: TCrateType; content: Longword ): PGear;
-function  SpawnFakeCrateAt(x, y: LongInt; crate: TCrateType; trap: boolean ): PGear;
+function  SpawnFakeCrateAt(x, y: LongInt; crate: TCrateType; explode: boolean; poison: boolean ): PGear;
 procedure ResurrectHedgehog(gear: PGear);
 procedure ProcessGears;
 procedure EndTurnCleanup;
@@ -107,7 +107,6 @@
             @doStepFirePunch,
             @doStepActionTimer,
             @doStepActionTimer,
-            @doStepActionTimer,
             @doStepParachute,
             @doStepAirAttack,
             @doStepAirBomb,
@@ -222,65 +221,15 @@
 gear^.SoundChannel:= -1;
 gear^.ImpactSound:= sndNone;
 gear^.nImpactSounds:= 0;
-gear^.AmmoType:= amNothing;
+// Define ammo association, if any.
+gear^.AmmoType:= GearKindAmmoTypeMap[Kind];
 
 if CurrentHedgehog <> nil then
     begin
     gear^.Hedgehog:= CurrentHedgehog;
     gear^.IntersectGear:= CurrentHedgehog^.Gear
     end;
-// Define ammo association, if any.
-case Kind of
-        gtGrenade: gear^.AmmoType:= amGrenade;
-          gtShell: gear^.AmmoType:= amBazooka;
-            gtBee: gear^.AmmoType:= amBee;
-    gtShotgunShot: gear^.AmmoType:= amShotgun;
-     gtPickHammer: gear^.AmmoType:= amPickHammer;
-           gtRope: gear^.AmmoType:= amRope;
-     gtDEagleShot: gear^.AmmoType:= amDEagle;
-       gtDynamite: gear^.AmmoType:= amDynamite;
-    gtClusterBomb, 
-        gtCluster: gear^.AmmoType:= amClusterBomb;
-         gtShover: gear^.AmmoType:= amBaseballBat;  // Shover is only used for baseball bat right now
-      gtFirePunch: gear^.AmmoType:= amFirePunch;
-      gtParachute: gear^.AmmoType:= amParachute;
-        gtAirBomb: gear^.AmmoType:= amAirAttack;
-      gtBlowTorch: gear^.AmmoType:= amBlowTorch;
-         gtGirder: gear^.AmmoType:= amGirder;
-       gtTeleport: gear^.AmmoType:= amTeleport;
-       gtSwitcher: gear^.AmmoType:= amSwitch;
-         gtMortar: gear^.AmmoType:= amMortar;
-           gtWhip: gear^.AmmoType:= amWhip;
-       gtKamikaze: gear^.AmmoType:= amKamikaze;
-           gtCake: gear^.AmmoType:= amCake;
-      gtSeduction: gear^.AmmoType:= amSeduction;
-     gtWatermelon,
-     gtMelonPiece: gear^.AmmoType:= amWatermelon;
-    gtHellishBomb: gear^.AmmoType:= amHellishBomb;
-          gtDrill: gear^.AmmoType:= amDrill;
-        gtBallGun,
-           gtBall: gear^.AmmoType:= amBallgun;
-        gtRCPlane: gear^.AmmoType:= amRCPlane;
-gtSniperRifleShot: gear^.AmmoType:= amSniperRifle;
-        gtJetpack: gear^.AmmoType:= amJetpack;
-        gtMolotov: gear^.AmmoType:= amMolotov;
-          gtBirdy, 
-            gtEgg: gear^.AmmoType:= amBirdy;
-         gtPortal: gear^.AmmoType:= amPortalGun;
-          gtPiano: gear^.AmmoType:= amPiano;
-        gtGasBomb: gear^.AmmoType:= amGasBomb;
-    gtSineGunShot: gear^.AmmoType:= amSineGun;
-   gtFlamethrower: gear^.AmmoType:= amFlamethrower;
-          gtSMine: gear^.AmmoType:= amSMine;
-         gtHammer, 
-      gtHammerHit: gear^.AmmoType:= amHammer;
-    gtResurrector: gear^.AmmoType:= amResurrector;
-       gtSnowball: gear^.AmmoType:= amSnowball;
-      gtStructure: gear^.AmmoType:= amStructure;  // TODO - This will undoubtedly change once there is more than one structure
-        gtLandGun: gear^.AmmoType:= amLandGun;
-         gtTardis: gear^.AmmoType:= amTardis;
-end;
-
+    
 case Kind of
      gtGrenade,
      gtClusterBomb,
@@ -341,6 +290,7 @@
                     dx.QWordValue:= GetRandom(100000000);
                     dy.isNegative:= false;
                     dy.QWordValue:= GetRandom(70000000);
+                    State:= State or gstInvisible;
                     if GetRandom(2) = 0 then dx := -dx;
                     Health:= random(vobFrameTicks);
                     Timer:= random(vobFramesCount);
@@ -1175,9 +1125,12 @@
 Gear:= GearsList;
 while Gear <> nil do
     begin
-    x:= hwRound(Gear^.X) + WorldDx;
-    y:= hwRound(Gear^.Y) + WorldDy;
-    RenderGear(Gear, x, y);
+    if Gear^.State and gstInvisible = 0 then
+        begin
+        x:= hwRound(Gear^.X) + WorldDx;
+        y:= hwRound(Gear^.Y) + WorldDy;
+        RenderGear(Gear, x, y);
+        end;
     Gear:= Gear^.NextGear
     end;
 end;
@@ -1685,13 +1638,14 @@
     SpawnCustomCrateAt := FollowGear;
 end;
 
-function SpawnFakeCrateAt(x, y: LongInt; crate: TCrateType; trap: boolean): PGear;
+function SpawnFakeCrateAt(x, y: LongInt; crate: TCrateType; explode: boolean; poison: boolean): PGear;
 begin
     FollowGear := AddGear(x, y, gtCase, 0, _0, _0, 0);
     cCaseFactor := 0;
+    FollowGear^.Pos := posCaseDummy;
     
-    if trap then FollowGear^.Pos := posCaseTrap
-    else FollowGear^.Pos := posCaseDummy;
+    if explode then FollowGear^.Pos := FollowGear^.Pos + posCaseExplode;
+    if poison then FollowGear^.Pos := FollowGear^.Pos + posCasePoison;
 
     case crate of
         HealthCrate: begin
--- a/hedgewars/uLandGraphics.pas	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/uLandGraphics.pas	Fri Jul 01 08:46:47 2011 +0200
@@ -715,7 +715,7 @@
    yy:= Y div 2;
    end;
 pixelsweep:= ((Land[Y, X] and $FF00) = 0) and (LandPixels[yy, xx] <> 0);
-if (((Land[Y, X] and lfDamaged) <> 0) and ((Land[Y, X] and lfIndestructible) = 0)) or pixelsweep then
+if ((Land[Y, X] > 255) and ((Land[Y, X] and lfIndestructible) = 0)) or pixelsweep then
     begin
     c:= 0;
     for i:= -1 to 1 do
@@ -738,8 +738,8 @@
                     else if Land[ny, nx] > 255 then inc(c);
                     end
                 end;
-
-    if c < 4 then // 0-3 neighbours
+    if (c < 2) or
+       ((c < 4) and (((Land[Y, X] and lfDamaged) <> 0) or pixelsweep)) then
         begin
         if ((Land[Y, X] and lfBasic) <> 0) and not disableLandBack then
             LandPixels[yy, xx]:= LandBackPixel(X, Y)
--- a/hedgewars/uScript.pas	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/uScript.pas	Fri Jul 01 08:46:47 2011 +0200
@@ -43,6 +43,7 @@
 function ScriptCall(fname : shortstring; par1, par2, par3: LongInt) : LongInt;
 function ScriptCall(fname : shortstring; par1, par2, par3, par4 : LongInt) : LongInt;
 function ScriptExists(fname : shortstring) : boolean;
+function ParseCommandOverride(key, value : shortstring) : shortstring;
 
 procedure initModule;
 procedure freeModule;
@@ -226,13 +227,13 @@
 function lc_spawnfakehealthcrate(L: Plua_State) : LongInt; Cdecl;
 var gear: PGear;
 begin
-    if lua_gettop(L) <> 3 then begin
+    if lua_gettop(L) <> 4 then begin
         LuaError('Lua: Wrong number of parameters passed to SpawnFakeHealthCrate!');
         lua_pushnil(L);
     end
     else begin
         gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2),
-            HealthCrate, lua_toboolean(L, 3));
+            HealthCrate, lua_toboolean(L, 3), lua_toboolean(L, 4));
         lua_pushinteger(L, gear^.uid);
     end;
     lc_spawnfakehealthcrate := 1;        
@@ -241,13 +242,13 @@
 function lc_spawnfakeammocrate(L: PLua_State): LongInt; Cdecl;
 var gear: PGear;
 begin
-    if lua_gettop(L) <> 3 then begin
+    if lua_gettop(L) <> 4 then begin
         LuaError('Lua: Wrong number of parameters passed to SpawnFakeAmmoCrate!');
         lua_pushnil(L);
     end
     else begin
         gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2),
-            AmmoCrate, lua_toboolean(L, 3));
+            AmmoCrate, lua_toboolean(L, 3), lua_toboolean(L, 4));
         lua_pushinteger(L, gear^.uid);
     end;
     lc_spawnfakeammocrate := 1;
@@ -256,13 +257,13 @@
 function lc_spawnfakeutilitycrate(L: PLua_State): LongInt; Cdecl;
 var gear: PGear;
 begin
-    if lua_gettop(L) <> 3 then begin
+    if lua_gettop(L) <> 4 then begin
         LuaError('Lua: Wrong number of parameters passed to SpawnFakeUtilityCrate!');
         lua_pushnil(L);
     end
     else begin  
         gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2),
-            UtilityCrate, lua_toboolean(L, 3));
+            UtilityCrate, lua_toboolean(L, 3), lua_toboolean(L, 4));
         lua_pushinteger(L, gear^.uid);
     end;
     lc_spawnfakeutilitycrate := 1;
@@ -1305,7 +1306,7 @@
         cWindSpeedf:= SignAs(cWindSpeed,cWindSpeed).QWordValue / SignAs(_1,_1).QWordValue;
         if cWindSpeed.isNegative then
             CWindSpeedf := -cWindSpeedf;
-        AddGear(0, 0, gtATSmoothWindCh, 0, _0, _0, 1)^.Tag:= hwRound(cWindSpeed * 72 / cMaxWindSpeed);
+        AddVisualGear(0, 0, vgtSmoothWindBar);
         end;
     lc_setwind:= 0
 end;
@@ -1588,6 +1589,25 @@
 GetGlobals;
 end;
 
+function ParseCommandOverride(key, value : shortstring) : shortstring;
+begin
+ParseCommandOverride:= value;
+if not ScriptExists('ParseCommandOverride') then exit;
+lua_getglobal(luaState, Str2PChar('ParseCommandOverride'));
+lua_pushstring(luaState, Str2PChar(key));
+lua_pushstring(luaState, Str2PChar(value));
+if lua_pcall(luaState, 2, 1, 0) <> 0 then
+    begin
+    LuaError('Lua: Error while calling ParseCommandOverride: ' + lua_tostring(luaState, -1));
+    lua_pop(luaState, 1)
+    end
+else
+    begin
+    ParseCommandOverride:= lua_tostring(luaState, -1);
+    lua_pop(luaState, 1)
+    end;
+end;
+
 function ScriptCall(fname : shortstring; par1: LongInt) : LongInt;
 begin
 ScriptCall:= ScriptCall(fname, par1, 0, 0, 0)
@@ -1669,14 +1689,23 @@
 end;
 
 procedure ScriptApplyAmmoStore;
-var i : LongInt;
+var i, j : LongInt;
 begin
 SetAmmoLoadout(ScriptAmmoLoadout);
 SetAmmoProbability(ScriptAmmoProbability);
 SetAmmoDelay(ScriptAmmoDelay);
 SetAmmoReinforcement(ScriptAmmoReinforcement);
-for i:= 0 to Pred(TeamsCount) do
-    AddAmmoStore;
+
+if (GameFlags and gfSharedAmmo) <> 0 then
+    for i:= 0 to Pred(ClansCount) do
+        AddAmmoStore
+else if (GameFlags and gfPerHogAmmo) <> 0 then
+    for i:= 0 to Pred(TeamsCount) do
+        for j:= 0 to Pred(TeamsArray[i]^.HedgehogsNumber) do
+            AddAmmoStore
+else 
+    for i:= 0 to Pred(TeamsCount) do
+        AddAmmoStore
 end;
 
 procedure initModule;
--- a/hedgewars/uTeams.pas	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/uTeams.pas	Fri Jul 01 08:46:47 2011 +0200
@@ -179,8 +179,7 @@
 end;
 
 procedure AfterSwitchHedgehog;
-var g: PGear;
-    i, t: LongInt;
+var i, t: LongInt;
     CurWeapon: PAmmo;
 
 begin
@@ -229,8 +228,7 @@
     cWindSpeedf:= SignAs(cWindSpeed,cWindSpeed).QWordValue / SignAs(_1,_1).QWordValue;
     if cWindSpeed.isNegative then
         CWindSpeedf := -cWindSpeedf;
-    g:= AddGear(0, 0, gtATSmoothWindCh, 0, _0, _0, 1);
-    g^.Tag:= hwRound(cWindSpeed * 72 / cMaxWindSpeed);
+    AddVisualGear(0, 0, vgtSmoothWindBar);
     AddFileLog('Wind = '+FloatToStr(cWindSpeed));
     end;
 
--- a/hedgewars/uTypes.pas	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/uTypes.pas	Fri Jul 01 08:46:47 2011 +0200
@@ -89,15 +89,15 @@
     TGearType = (gtGrenade, gtHedgehog, gtShell, gtGrave, gtBee, // 4
             gtShotgunShot, gtPickHammer, gtRope, gtMine, gtCase, // 9
             gtDEagleShot, gtDynamite, gtClusterBomb, gtCluster, gtShover, // 14
-            gtFlame, gtFirePunch, gtATStartGame, gtATSmoothWindCh, // 18
-            gtATFinishGame, gtParachute, gtAirAttack, gtAirBomb, gtBlowTorch, // 23
-            gtGirder, gtTeleport, gtSwitcher, gtTarget, gtMortar, // 28
-            gtWhip, gtKamikaze, gtCake, gtSeduction, gtWatermelon, gtMelonPiece, // 34
-            gtHellishBomb, gtWaterUp, gtDrill, gtBallGun, gtBall, gtRCPlane, // 40
-            gtSniperRifleShot, gtJetpack, gtMolotov, gtExplosives, gtBirdy, // 45
-            gtEgg, gtPortal, gtPiano, gtGasBomb, gtSineGunShot, gtFlamethrower, // 51
-            gtSMine, gtPoisonCloud, gtHammer, gtHammerHit, gtResurrector, // 56
-            gtNapalmBomb, gtSnowball, gtFlake, gtStructure, gtLandGun, gtTardis); // 62
+            gtFlame, gtFirePunch, gtATStartGame, // 17
+            gtATFinishGame, gtParachute, gtAirAttack, gtAirBomb, gtBlowTorch, // 22
+            gtGirder, gtTeleport, gtSwitcher, gtTarget, gtMortar, // 27
+            gtWhip, gtKamikaze, gtCake, gtSeduction, gtWatermelon, gtMelonPiece, // 33
+            gtHellishBomb, gtWaterUp, gtDrill, gtBallGun, gtBall, gtRCPlane, // 39
+            gtSniperRifleShot, gtJetpack, gtMolotov, gtExplosives, gtBirdy, // 44
+            gtEgg, gtPortal, gtPiano, gtGasBomb, gtSineGunShot, gtFlamethrower, // 50
+            gtSMine, gtPoisonCloud, gtHammer, gtHammerHit, gtResurrector, // 55
+            gtNapalmBomb, gtSnowball, gtFlake, gtStructure, gtLandGun, gtTardis); // 61
 
     // Gears that are _only_ of visual nature (e.g. background stuff, visual effects, speechbubbles, etc.)
     TVisualGearType = (vgtFlake, vgtCloud, vgtExplPart, vgtExplPart2, vgtFire,
@@ -105,7 +105,8 @@
             vgtSteam, vgtAmmo, vgtSmoke, vgtSmokeWhite, vgtHealth, vgtShell,
             vgtDust, vgtSplash, vgtDroplet, vgtSmokeRing, vgtBeeTrace, vgtEgg,
             vgtFeather, vgtHealthTag, vgtSmokeTrace, vgtEvilTrace, vgtExplosion,
-            vgtBigExplosion, vgtChunk, vgtNote, vgtLineTrail, vgtBulletHit, vgtCircle);
+            vgtBigExplosion, vgtChunk, vgtNote, vgtLineTrail, vgtBulletHit, vgtCircle,
+            vgtSmoothWindBar);
 
     TGearsType = set of TGearType;
 
@@ -274,6 +275,7 @@
         Tex: PTexture;
         alpha, scale: GLfloat;
         Hedgehog: PHedgehog;
+        Tag: LongInt;
         Text: shortstring;
         Tint: Longword;
         uid: Longword;
--- a/hedgewars/uVariables.pas	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/uVariables.pas	Fri Jul 01 08:46:47 2011 +0200
@@ -2170,6 +2170,71 @@
             ejectY: -3)
         );
 
+    GearKindAmmoTypeMap : array [TGearType] of TAmmoType = (    
+(*        gtGrenade *)   amGrenade
+(*       gtHedgehog *) , amNothing
+(*          gtShell *) , amBazooka
+(*          gtGrave *) , amNothing
+(*            gtBee *) , amBee
+(*    gtShotgunShot *) , amShotgun
+(*     gtPickHammer *) , amPickHammer
+(*           gtRope *) , amRope
+(*           gtMine *) , amNothing
+(*           gtCase *) , amNothing
+(*     gtDEagleShot *) , amDEagle
+(*       gtDynamite *) , amDynamite
+(*    gtClusterBomb *) , amClusterBomb
+(*        gtCluster *) , amClusterBomb
+(*         gtShover *) , amBaseballBat  // Shover is only used for baseball bat right now
+(*          gtFlame *) , amNothing
+(*      gtFirePunch *) , amFirePunch
+(*    gtATStartGame *) , amNothing
+(*   gtATFinishGame *) , amNothing
+(*      gtParachute *) , amParachute
+(*      gtAirAttack *) , amAirAttack
+(*        gtAirBomb *) , amAirAttack
+(*      gtBlowTorch *) , amBlowTorch
+(*         gtGirder *) , amGirder
+(*       gtTeleport *) , amTeleport
+(*       gtSwitcher *) , amSwitch
+(*         gtTarget *) , amNothing
+(*         gtMortar *) , amMortar
+(*           gtWhip *) , amWhip
+(*       gtKamikaze *) , amKamikaze
+(*           gtCake *) , amCake
+(*      gtSeduction *) , amSeduction
+(*     gtWatermelon *) , amWatermelon
+(*     gtMelonPiece *) , amWatermelon
+(*    gtHellishBomb *) , amHellishBomb
+(*        gtWaterUp *) , amNothing
+(*          gtDrill *) , amDrill
+(*        gtBallGun *) , amBallgun
+(*           gtBall *) , amBallgun
+(*        gtRCPlane *) , amRCPlane
+(*gtSniperRifleShot *) , amSniperRifle
+(*        gtJetpack *) , amJetpack
+(*        gtMolotov *) , amMolotov
+(*     gtExplosives *) , amNothing
+(*          gtBirdy *) , amBirdy
+(*            gtEgg *) , amBirdy
+(*         gtPortal *) , amPortalGun
+(*          gtPiano *) , amPiano
+(*        gtGasBomb *) , amGasBomb
+(*    gtSineGunShot *) , amSineGun
+(*   gtFlamethrower *) , amFlamethrower
+(*          gtSMine *) , amSMine
+(*    gtPoisonCloud *) , amNothing
+(*         gtHammer *) , amHammer
+(*      gtHammerHit *) , amHammer
+(*    gtResurrector *) , amResurrector
+(*    gtPoisonCloud *) , amNothing
+(*       gtSnowball *) , amSnowball
+(*          gtFlake *) , amNothing
+(*      gtStructure *) , amStructure  // TODO - This will undoubtedly change once there is more than one structure
+(*        gtLandGun *) , amLandGun
+(*         gtTardis *) , amTardis
+    );
+
 var
     Land: TCollisionArray;
     LandPixels: TLandArray;
--- a/hedgewars/uVisualGears.pas	Wed Jun 29 18:09:24 2011 +0200
+++ b/hedgewars/uVisualGears.pas	Fri Jul 01 08:46:47 2011 +0200
@@ -108,7 +108,8 @@
             @doStepNote,
             @doStepLineTrail,
             @doStepBulletHit,
-            @doStepCircle
+            @doStepCircle,
+            @doStepSmoothWindBar
         );
 
 function  AddVisualGear(X, Y: LongInt; Kind: TVisualGearType; State: LongWord = 0; Critical: Boolean = false): PVisualGear;
@@ -134,7 +135,8 @@
     vgtExplosion,
     vgtSmokeTrace,
     vgtEvilTrace,
-    vgtNote]) then
+    vgtNote,
+    vgtSmoothWindBar]) then
     begin
       AddVisualGear:= nil;
       exit
@@ -327,6 +329,7 @@
                 Frame:= 7;
                 Angle := 0;
                 end;
+vgtSmoothWindBar: Tag:= hwRound(cWindSpeed * 72 / cMaxWindSpeed);
         end;
 
 if State <> 0 then gear^.State:= State;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/theme_editor.html	Fri Jul 01 08:46:47 2011 +0200
@@ -0,0 +1,159 @@
+<!doctype html>
+<html>
+    <head>
+        <title>Hedgewars Theme Editor</title>
+        <script type="text/javascript">
+            var sky, clouds, horizont, water, land, border;
+            var skyColor, waterTopColor, waterBottomColor;
+            var elements = 7;
+            var landArray;
+            
+            function landFunction(x){
+                return 384 - 192 * Math.sin(x * Math.PI/512);
+            }
+            
+            function tryToDraw(){
+                if (--elements <= 0) {
+                    draw();
+                }
+            }
+        
+            function load(){
+                    var canvas = document.getElementById('preview');
+                    if (canvas.getContext){
+                        var ctx = canvas.getContext('2d');
+                    
+                        ctx.fillStyle = '#0b294b';
+                        ctx.fillRect(0, 0, 512, 384);
+                        
+                        ctx.font = "40pt Arial";
+                        ctx.fillStyle = '#2b7bd5';
+                        ctx.fillText('Loading Images...', 32, 212);
+                    }
+                    
+                    sky = new Image();
+                    sky.onload = tryToDraw;
+                    sky.src = 'http://hedgewars.googlecode.com/hg/share/hedgewars/Data/Themes/Nature/Sky.png';
+          
+                    clouds = new Image();
+                    clouds.onload = tryToDraw;
+                    clouds.src = 'http://hedgewars.googlecode.com/hg/share/hedgewars/Data/Graphics/Clouds.png';
+          
+                    horizont = new Image();
+                    horizont.onload = tryToDraw;
+                    horizont.src = 'http://hedgewars.googlecode.com/hg/share/hedgewars/Data/Themes/Nature/horizont.png';
+          
+                    land = new Image();
+                    land.onload = tryToDraw;
+                    land.src = 'http://hedgewars.googlecode.com/hg/share/hedgewars/Data/Themes/Nature/LandTex.png';
+          
+                    border = new Image();
+                    border.onload = tryToDraw;
+                    border.src = 'http://hedgewars.googlecode.com/hg/share/hedgewars/Data/Themes/Nature/Border.png';
+          
+                    water = new Image();
+                    water.onload = tryToDraw;
+                    water.src = 'http://hedgewars.googlecode.com/hg/share/hedgewars/Data/Graphics/BlueWater.png';
+                    
+                    landArray = new Array(512);
+                    for (var x = 0; x < landArray.length; x++)
+                        landArray[x] = landFunction(x);
+                    
+                    skyColor = '#131252';
+                    document.getElementById('skyColor').value = skyColor;
+                    
+                    waterTopColor = '#555C9D';
+                    document.getElementById('waterTopColor').value = waterTopColor;
+                    
+                    waterBottomColor = '#343C7D';
+                    document.getElementById('waterBottomColor').value = waterBottomColor;
+                    
+                    tryToDraw();
+            }
+            
+            function draw(){
+                var canvas = document.getElementById('preview');
+                if (canvas.getContext){
+                    var ctx = canvas.getContext('2d');
+                    
+                    ctx.fillStyle = skyColor;
+                    ctx.fillRect(0, 0, 512, 384);
+                    
+                    ctx.drawImage(sky, 0, 64, 512, 256);
+          
+                    for (var i = 0; i < 4; i++)
+                        ctx.drawImage(clouds, 0, i * 128, 256, 128, i * 128, 64, 128, 64);
+          
+                    ctx.drawImage(horizont, 0, 192, 512, 128);
+                    
+                    ctx.save();
+                    
+                    ctx.beginPath();
+                    ctx.moveTo(0, 384);
+                    for (var x = 0; x < landArray.length; x++)
+                        ctx.lineTo(x, landArray[x]);
+                    ctx.clip();
+                    
+                    for (var i = 0; i < 2; i++)
+                    	for (var k = 0; k < 2; k++)
+                    		ctx.drawImage(land, i * 320, k * 240, 320, 240);
+                    
+                    ctx.restore();
+                    
+                    var k = 0;
+                    for (var x = 0; x < landArray.length; x++) {
+                        if (++k == 64)
+                            k = 0;
+                        ctx.drawImage(border, k, 0, 2, 16, x, landArray[x] - 4, 1, 8);
+                    }
+                        
+                    
+                    var gradient = ctx.createLinearGradient(0, 320, 0, 384);
+                    gradient.addColorStop(0, waterTopColor);
+                    gradient.addColorStop(1, waterBottomColor);
+                    ctx.fillStyle = gradient;
+                    ctx.fillRect(0, 320, 512, 384);
+          
+                    for (var i = 0; i < 8; i++)
+                        ctx.drawImage(water, i * 64, 308, 64, 24);
+                }
+            }
+        </script>
+        <style type="text/css">
+            canvas { border: 1px solid black; }
+        </style>
+    </head>
+    <body onload="load();">
+        <h1>Hedgewars Theme editor</h1>
+        <canvas id="preview" width="512" height="384"></canvas><br>
+        <table>
+        <tr><td>Sky:</td><td>
+        <input id="sky" type="file" accept="image/png" onchange="sky.src = window.URL.createObjectURL(this.files[0])"></input>
+        </td></tr>
+        <tr><td>Sky Color:</td><td>
+        <input id="skyColor" type="color" onchange="skyColor = this.value; draw()"></input>
+        </td></tr>
+        <tr><td>Clouds:</td><td>
+        <input id="clouds" type="file" accept="image/png" onchange="clouds.src = window.URL.createObjectURL(this.files[0])"></input>
+        </td></tr>
+        <tr><td>Horizont:</td><td>
+        <input id="horizont" type="file" accept="image/png" onchange="horizont.src = window.URL.createObjectURL(this.files[0])"></input>
+        </td></tr>
+        <tr><td>Land:</td><td>
+        <input id="land" type="file" accept="image/png" onchange="land.src = window.URL.createObjectURL(this.files[0])"></input>
+        </td></tr>
+        <tr><td>Border:</td><td>
+        <input id="border" type="file" accept="image/png" onchange="border.src = window.URL.createObjectURL(this.files[0])"></input>
+        </td></tr>
+        <tr><td>Water:</td><td>
+        <input id="water" type="file" accept="image/png" onchange="water.src = window.URL.createObjectURL(this.files[0])"></input>
+        </td></tr>
+        <tr><td>Water Top Color:</td><td>
+        <input id="waterTopColor" type="color" onchange="waterTopColor = this.value; draw()"></input>
+        </td></tr>
+        <tr><td>Water Bottom Color:</td><td>
+        <input id="waterBottomColor" type="color" onchange="waterBottomColor = this.value; draw()"></input>
+        </td></tr>
+        </table>
+    </body>
+</html>
--- a/share/hedgewars/Data/Scripts/Multiplayer/Random_Weapon.lua	Wed Jun 29 18:09:24 2011 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/Random_Weapon.lua	Fri Jul 01 08:46:47 2011 +0200
@@ -46,7 +46,7 @@
 
 function onGameInit()
     -- Limit flags that can be set, but allow game schemes to be used
-    GameFlags = band(bor(GameFlags, gfResetWeps), bnot(gfInfAttack + gfPerHogAmmo))
+    GameFlags = band(bor(GameFlags, gfResetWeps), bnot(gfInfAttack))
     -- Set a custom game goal that will show together with the scheme ones
     Goals = loc("Each turn you get one random weapon")
 end
--- a/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.lua	Wed Jun 29 18:09:24 2011 +0200
+++ b/share/hedgewars/Data/Scripts/Multiplayer/The_Specialists.lua	Fri Jul 01 08:46:47 2011 +0200
@@ -1,5 +1,5 @@
 ----------------------------------
--- THE SPECIALISTS MODE 0.2
+-- THE SPECIALISTS MODE 0.3
 -- by mikade
 ----------------------------------
 
@@ -16,13 +16,19 @@
 -- removed some deprecated variables/methods
 -- fixed lack of portal reset
 
+----------------
+-- version 0.3
+----------------
+-- added switching on start
+-- removed switch from engineer weaponset
+
 --------------------
 --TO DO
 --------------------
 
 -- add proper gameflag checking, maybe
 -- set crate drops etc.
--- assuming place hog mode + gfinfattack doesn't get the fix: somehow end turn after teleport
+-- add alternative switch
 
 loadfile(GetDataPath() .. "Scripts/Locale.lua")()
 
@@ -31,6 +37,8 @@
 
 local currName 
 local lastName
+local started = false
+local switchStage = 0
 
 function CreateTeam()
 
@@ -155,7 +163,7 @@
 		AddAmmo(CurrentHedgehog, amGirder, 2)
 		AddAmmo(CurrentHedgehog, amBlowTorch, 1)
 		AddAmmo(CurrentHedgehog, amPickHammer, 1)	
-		AddAmmo(CurrentHedgehog, amSwitch, 2)	
+		--AddAmmo(CurrentHedgehog, amSwitch, 2)	
 	elseif n == "Ninja" then
 		AddAmmo(CurrentHedgehog, amRope, 100)
 		AddAmmo(CurrentHedgehog, amParachute, 100)
@@ -215,7 +223,13 @@
 	currName = GetHogName(CurrentHedgehog)
 	lastName = GetHogName(CurrentHedgehog)
 	AssignAmmo()
-	AddAmmo(CurrentHedgehog, amSwitch, 1)
+	
+	--AddAmmo(CurrentHedgehog, amSwitch, 1)
+	---------------
+	--switch	
+	started = false
+	switchStage = 0
+	---------------
 end
 
 function onGameTick()
@@ -229,6 +243,22 @@
 			AssignAmmo()		
 		end
 
+		if (TurnTimeLeft > 0) and (TurnTimeLeft ~= TurnTime) and (switchStage < 100) then			
+			
+			switchStage = switchStage + 1	
+			
+			if switchStage == 10 then
+				AddAmmo(CurrentHedgehog, amSwitch, 1)
+			elseif switchStage == 20 then
+				ParseCommand("setweap " .. string.char(amSwitch))
+			elseif switchStage == 30 then
+				SetGearMessage(CurrentHedgehog,gmAttack) 
+				switchStage = 110
+			end
+		end		
+		
+		--------------------------------------------------------------------------------------
+
 		lastName = currName
 
 	end
@@ -249,7 +279,7 @@
 end
 
 function onAmmoStoreInit()
-
+--
 end