Move some command handlers out of uCommands into more appropriate places, thus removing some dependencies. Ideally uCommands shouldn't depend on anything (except for uTypes and uConsts probably)
authorunc0rr
Sun, 21 Nov 2010 17:48:58 +0300
changeset 4398 36d7e4b6ca81
parent 4397 ab577db125c4
child 4399 87bc4a9e6ef0
Move some command handlers out of uCommands into more appropriate places, thus removing some dependencies. Ideally uCommands shouldn't depend on anything (except for uTypes and uConsts probably)
hedgewars/CCHandlers.inc
hedgewars/uCommands.pas
hedgewars/uGears.pas
hedgewars/uLand.pas
hedgewars/uSound.pas
hedgewars/uStore.pas
hedgewars/uTeams.pas
hedgewars/uUtils.pas
--- a/hedgewars/CCHandlers.inc	Sun Nov 21 09:37:48 2010 -0500
+++ b/hedgewars/CCHandlers.inc	Sun Nov 21 17:48:58 2010 +0300
@@ -16,17 +16,6 @@
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 *)
 
-function CheckNoTeamOrHH: boolean;
-var bRes: boolean;
-begin
-bRes:= (CurrentTeam = nil) or (CurrentHedgehog^.Gear = nil);
-{$IFDEF DEBUGFILE}
-if bRes then
-if CurrentTeam = nil then AddFileLog('CONSOLE: CurTeam = nil')
-                        else AddFileLog('CONSOLE: CurTeam <> nil, Gear = nil');
-{$ENDIF}
-CheckNoTeamOrHH:= bRes;
-end;
 ////////////////////////////////////////////////////////////////////////////////
 procedure chQuit(var s: shortstring);
 const prevGState: TGameState = gsConfirm;
@@ -73,31 +62,6 @@
 end
 end;
 
-procedure chAddTeam(var s: shortstring);
-var Color: Longword;
-    ts, cs: shortstring;
-begin
-cs:= '';
-ts:= '';
-if isDeveloperMode then
-begin
-SplitBySpace(s, cs);
-SplitBySpace(cs, ts);
-val(cs, Color);
-TryDo(Color <> 0, 'Error: black team color', true);
-
-// color is always little endian so the mask must be constant also in big endian archs
-Color:= Color or $FF000000;
-    
-AddTeam(Color);
-CurrentTeam^.TeamName:= ts;
-CurrentTeam^.PlayerHash:= s;
-if GameType in [gmtDemo, gmtSave] then CurrentTeam^.ExtDriven:= true;
-
-CurrentTeam^.voicepack:= AskForVoicepack('Default')
-end
-end;
-
 procedure chTeamLocal(var s: shortstring);
 begin
 s:= s; // avoid compiler hint
@@ -122,14 +86,6 @@
 CurrentTeam^.FortName:= s
 end;
 
-procedure chVoicepack(var s: shortstring);
-begin
-if CurrentTeam = nil then OutError(errmsgIncorrectUse + ' "/voicepack"', true);
-if s[1]='"' then Delete(s, 1, 1);
-if s[byte(s[0])]='"' then Delete(s, byte(s[0]), 1);
-CurrentTeam^.voicepack:= AskForVoicepack(s)
-end;
-
 procedure chFlag(var s: shortstring);
 begin
 if CurrentTeam = nil then OutError(errmsgIncorrectUse + ' "/flag"', true);
@@ -145,37 +101,6 @@
 ScriptLoad(s)
 end;
 
-procedure chAddHH(var id: shortstring);
-var s: shortstring;
-    Gear: PGear;
-begin
-s:= '';
-if (not isDeveloperMode) or (CurrentTeam = nil) then exit;
-with CurrentTeam^ do
-    begin
-    SplitBySpace(id, s);
-    CurrentHedgehog:= @Hedgehogs[HedgehogsNumber];
-    val(id, CurrentHedgehog^.BotLevel);
-    Gear:= AddGear(0, 0, gtHedgehog, 0, _0, _0, 0);
-    SplitBySpace(s, id);
-    val(s, Gear^.Health);
-    TryDo(Gear^.Health > 0, 'Invalid hedgehog health', true);
-    Gear^.Hedgehog^.Team:= CurrentTeam;
-    if (GameFlags and gfSharedAmmo) <> 0 then CurrentHedgehog^.AmmoStore:= Clan^.ClanIndex
-    else if (GameFlags and gfPerHogAmmo) <> 0 then
-        begin
-        AddAmmoStore;
-        CurrentHedgehog^.AmmoStore:= StoreCnt - 1
-        end
-    else CurrentHedgehog^.AmmoStore:= TeamsCount - 1;
-    CurrentHedgehog^.Gear:= Gear;
-    CurrentHedgehog^.Name:= id;
-    CurrentHedgehog^.InitialHealth:= Gear^.Health;
-    CurrHedgehog:= HedgehogsNumber;
-    inc(HedgehogsNumber)
-    end
-end;
-
 procedure chSetHat(var s: shortstring);
 begin
 if (not isDeveloperMode) or (CurrentTeam = nil) then exit;
@@ -191,19 +116,6 @@
     end;
 end;
 
-procedure chSetHHCoords(var x: shortstring);
-var y: shortstring;
-    t: Longint;
-begin
-y:= '';
-if (not isDeveloperMode) or (CurrentHedgehog = nil) or (CurrentHedgehog^.Gear = nil) then exit;
-SplitBySpace(x, y);
-val(x, t);
-CurrentHedgehog^.Gear^.X:= int2hwFloat(t);
-val(y, t);
-CurrentHedgehog^.Gear^.Y:= int2hwFloat(t)
-end;
-
 procedure chSetAmmoLoadout(var descr: shortstring);
 begin
 SetAmmoLoadout(descr)
@@ -548,38 +460,6 @@
     end
 end;
 
-procedure chHogSay(var s: shortstring);
-var Gear: PVisualGear;
-    text: shortstring;
-begin
-text:= copy(s, 2, Length(s)-1);
-if CheckNoTeamOrHH
-or ((CurrentHedgehog^.Gear^.State and gstHHDriven) = 0) then
-    begin
-    chSay(text);
-    exit
-    end;
-
-if not CurrentTeam^.ExtDriven then SendIPC('h' + s);
-
-if byte(s[1]) < 4 then
-    begin
-    Gear:= AddVisualGear(0, 0, vgtSpeechBubble);
-    if Gear <> nil then
-    begin
-    Gear^.Hedgehog:= CurrentHedgehog;
-    Gear^.Text:= text;
-    Gear^.FrameTicks:= byte(s[1])
-    end
-    end
-else
-    begin
-    SpeechType:= byte(s[1])-3;
-    SpeechText:= text
-    end;
-
-end;
-
 procedure doPut(putX, putY: LongInt; fromAI: boolean);
 begin
 if CheckNoTeamOrHH or isPaused then exit;
@@ -636,14 +516,6 @@
 flagMakeCapture:= true
 end;
 
-procedure chSkip(var s: shortstring);
-begin
-s:= s; // avoid compiler hint
-if not CurrentTeam^.ExtDriven then SendIPC(',');
-uStats.Skipped;
-skipFlag:= true
-end;
-
 procedure chSetMap(var s: shortstring);
 begin
 if isDeveloperMode then
@@ -693,81 +565,6 @@
     end
 end;
 
-procedure chFullScr(var s: shortstring);
-var flags: Longword = 0;
-    ico: PSDL_Surface;
-{$IFDEF DEBUGFILE}
-    buf: array[byte] of char;
-{$ENDIF}
-begin
-    s:= s; // avoid compiler hint
-    if Length(s) = 0 then cFullScreen:= not cFullScreen
-    else cFullScreen:= s = '1';
-
-{$IFDEF DEBUGFILE}
-    buf[0]:= char(0); // avoid compiler hint
-    AddFileLog('Prepare to change video parameters...');
-{$ENDIF}
-
-    flags:= SDL_OPENGL;// or SDL_RESIZABLE;
-
-    if cFullScreen then
-        flags:= flags or SDL_FULLSCREEN;
-
-{$IFDEF SDL_IMAGE_NEWER}
-    WriteToConsole('Init SDL_image... ');
-    SDLTry(IMG_Init(IMG_INIT_PNG) <> 0, true);
-    WriteLnToConsole(msgOK);
-{$ENDIF}
-    // load engine icon
-{$IFDEF DARWIN}
-    ico:= LoadImage(Pathz[ptGraphics] + '/hwengine_mac', ifIgnoreCaps);
-{$ELSE}
-    ico:= LoadImage(Pathz[ptGraphics] + '/hwengine', ifIgnoreCaps);
-{$ENDIF}
-    if ico <> nil then
-    begin
-        SDL_WM_SetIcon(ico, 0);
-        SDL_FreeSurface(ico)
-    end;
-    
-    // set window caption
-    SDL_WM_SetCaption('Hedgewars', nil);
-    
-    if SDLPrimSurface <> nil then
-    begin
-{$IFDEF DEBUGFILE}
-        AddFileLog('Freeing old primary surface...');
-{$ENDIF}
-        SDL_FreeSurface(SDLPrimSurface);
-        SDLPrimSurface:= nil;
-    end;
-    
-{$IFDEF SDL13}
-    if SDLwindow = nil then
-    begin
-        SDLwindow:= SDL_CreateWindow('Hedgewars', 0, 0, cScreenWidth, cScreenHeight,
-                        SDL_WINDOW_OPENGL or SDL_WINDOW_SHOWN    
-                        {$IFDEF IPHONEOS} or SDL_WINDOW_BORDERLESS{$ENDIF});     
-        SDL_CreateRenderer(SDLwindow, -1, 0);
-    end;
-    
-    SDL_SetRenderDrawColor(0, 0, 0, 255);    
-    SDL_RenderFill(nil);     
-    SDL_RenderPresent();
-{$ELSE}
-    SDLPrimSurface:= SDL_SetVideoMode(cScreenWidth, cScreenHeight, cBits, flags);
-    SDLTry(SDLPrimSurface <> nil, true);
-    PixelFormat:= SDLPrimSurface^.format;
-{$ENDIF}
-
-{$IFDEF DEBUGFILE}
-    AddFileLog('Setting up OpenGL...');
-    AddFileLog('SDL video driver: ' + shortstring(SDL_VideoDriverName(buf, sizeof(buf))));
-{$ENDIF}
-    SetupOpenGL();
-end;
-
 procedure chVol_p(var s: shortstring);
 begin
 s:= s; // avoid compiler hint
@@ -848,25 +645,3 @@
     uChat.showAll:= not uChat.showAll
 end;
 
-procedure chLandCheck(var s: shortstring);
-begin
-{$IFDEF DEBUGFILE}
-    AddFileLog('CheckLandDigest: ' + s + ' digest : ' + digest);
-{$ENDIF}
-    if digest = '' then
-        digest:= s
-    else
-        TryDo(s = digest, 'Different maps generated, sorry', true);
-end;
-
-procedure chSendLandDigest(var s: shortstring);
-var adler, i: LongInt;
-begin
-    adler:= 1;
-    for i:= 0 to LAND_HEIGHT-1 do
-        Adler32Update(adler, @Land[i,0], LAND_WIDTH);
-    s:= 'M' + IntToStr(adler);
-
-    chLandCheck(s);
-    SendIPCRaw(@s[0], Length(s) + 1)
-end;
--- a/hedgewars/uCommands.pas	Sun Nov 21 09:37:48 2010 -0500
+++ b/hedgewars/uCommands.pas	Sun Nov 21 17:48:58 2010 +0300
@@ -10,14 +10,15 @@
 
 procedure initModule;
 procedure freeModule;
+procedure RegisterVariable(Name: shortstring; VType: TVariableType; p: pointer; Trusted: boolean);
 procedure ParseCommand(CmdStr: shortstring; TrustedSource: boolean);
 procedure StopMessages(Message: Longword);
 procedure doPut(putX, putY: LongInt; fromAI: boolean);
 
 implementation
-uses uStore, Types, uConsts, uGears, uTeams, uIO, uKeys, uMobile,
-     uRandom, uAmmos, uStats, uChat, SDLh, uSound, uVisualGears, uScript, uTypes,
-     uVariables, uConsole, uFloat, uUtils, Adler32;
+uses Types, uConsts, uIO, uKeys, uMobile,
+     uRandom, uAmmos, uChat, SDLh, uScript, uTypes,
+     uVariables, uConsole, uUtils;
 
 type  PVariable = ^TVariable;
       TVariable = record
@@ -31,7 +32,7 @@
 var
       Variables: PVariable;
 
-function RegisterVariable(Name: shortstring; VType: TVariableType; p: pointer; Trusted: boolean): PVariable;
+procedure RegisterVariable(Name: shortstring; VType: TVariableType; p: pointer; Trusted: boolean);
 var value: PVariable;
 begin
 New(value);
@@ -47,8 +48,6 @@
                         value^.Next:= Variables;
                         Variables:= value
                         end;
-
-RegisterVariable:= value;
 end;
 
 
@@ -125,15 +124,12 @@
     isDeveloperMode:= true;
 
     // NOTE: please, keep most frequently used commands on bottom
-    RegisterVariable('landcheck',vtCommand, @chLandCheck    , false);
-    RegisterVariable('sendlanddigest',vtCommand, @chSendLandDigest, false);
     RegisterVariable('flag'    , vtCommand, @chFlag         , false);
     RegisterVariable('script'  , vtCommand, @chScript       , false);
     RegisterVariable('proto'   , vtCommand, @chCheckProto   , true );
     RegisterVariable('spectate', vtBoolean, @fastUntilLag   , false);
     RegisterVariable('capture' , vtCommand, @chCapture      , true );
     RegisterVariable('rotmask' , vtCommand, @chRotateMask   , true );
-    RegisterVariable('addteam' , vtCommand, @chAddTeam      , false);
     RegisterVariable('rdriven' , vtCommand, @chTeamLocal    , false);
     RegisterVariable('map'     , vtCommand, @chSetMap       , false);
     RegisterVariable('theme'   , vtCommand, @chSetTheme     , false);
@@ -159,12 +155,9 @@
     RegisterVariable('turntime', vtLongInt, @cHedgehogTurnTime, false);
     RegisterVariable('minestime',vtLongInt, @cMinesTime     , false);
     RegisterVariable('fort'    , vtCommand, @chFort         , false);
-    RegisterVariable('voicepack',vtCommand, @chVoicepack    , false);
     RegisterVariable('grave'   , vtCommand, @chGrave        , false);
     RegisterVariable('bind'    , vtCommand, @chBind         , true );
-    RegisterVariable('addhh'   , vtCommand, @chAddHH        , false);
     RegisterVariable('hat'     , vtCommand, @chSetHat       , false);
-    RegisterVariable('hhcoords', vtCommand, @chSetHHCoords  , false);
     RegisterVariable('ammloadt', vtCommand, @chSetAmmoLoadout, false);
     RegisterVariable('ammdelay', vtCommand, @chSetAmmoDelay, false);
     RegisterVariable('ammprob',  vtCommand, @chSetAmmoProbability, false);
@@ -177,11 +170,9 @@
     RegisterVariable('zoomin'  , vtCommand, @chZoomIn       , true );
     RegisterVariable('zoomout' , vtCommand, @chZoomOut      , true );
     RegisterVariable('zoomreset',vtCommand, @chZoomReset    , true );
-    RegisterVariable('skip'    , vtCommand, @chSkip         , false);
     RegisterVariable('history' , vtCommand, @chHistory      , true );
     RegisterVariable('chat'    , vtCommand, @chChat         , true );
     RegisterVariable('say'     , vtCommand, @chSay          , true );
-    RegisterVariable('hogsay'  , vtCommand, @chHogSay       , true );
     RegisterVariable('team'    , vtCommand, @chTeamSay      , true );
     RegisterVariable('ammomenu', vtCommand, @chAmmoMenu     , true);
     RegisterVariable('+precise', vtCommand, @chPrecise_p    , false);
@@ -205,7 +196,6 @@
     RegisterVariable('put'     , vtCommand, @chPut          , false);
     RegisterVariable('ljump'   , vtCommand, @chLJump        , false);
     RegisterVariable('hjump'   , vtCommand, @chHJump        , false);
-    RegisterVariable('fullscr' , vtCommand, @chFullScr      , true );
     RegisterVariable('+volup'  , vtCommand, @chVol_p        , true );
     RegisterVariable('-volup'  , vtCommand, @chVol_m        , true );
     RegisterVariable('+voldown', vtCommand, @chVol_m        , true );
--- a/hedgewars/uGears.pas	Sun Nov 21 09:37:48 2010 -0500
+++ b/hedgewars/uGears.pas	Sun Nov 21 17:48:58 2010 +0300
@@ -1711,8 +1711,51 @@
     end
 end;
 
+
+procedure chSkip(var s: shortstring);
+begin
+s:= s; // avoid compiler hint
+if not CurrentTeam^.ExtDriven then SendIPC(',');
+uStats.Skipped;
+skipFlag:= true
+end;
+
+procedure chHogSay(var s: shortstring);
+var Gear: PVisualGear;
+    text: shortstring;
+begin
+    text:= copy(s, 2, Length(s) - 1);
+    if CheckNoTeamOrHH
+    or ((CurrentHedgehog^.Gear^.State and gstHHDriven) = 0) then
+        begin
+        ParseCommand('say ' + text, true);
+        exit
+        end;
+
+    if not CurrentTeam^.ExtDriven then SendIPC('h' + s);
+
+    if byte(s[1]) < 4 then
+        begin
+        Gear:= AddVisualGear(0, 0, vgtSpeechBubble);
+        if Gear <> nil then
+            begin
+            Gear^.Hedgehog:= CurrentHedgehog;
+            Gear^.Text:= text;
+            Gear^.FrameTicks:= byte(s[1])
+            end
+        end
+    else
+        begin
+        SpeechType:= byte(s[1])-3;
+        SpeechText:= text
+        end;
+end;
+
 procedure initModule;
 begin
+    RegisterVariable('skip', vtCommand, @chSkip, false);
+    RegisterVariable('hogsay', vtCommand, @chHogSay, true );
+
     CurAmmoGear:= nil;
     GearsList:= nil;
     KilledHHs:= 0;
--- a/hedgewars/uLand.pas	Sun Nov 21 09:37:48 2010 -0500
+++ b/hedgewars/uLand.pas	Sun Nov 21 17:48:58 2010 +0300
@@ -35,7 +35,7 @@
 
 implementation
 uses uConsole, uStore, uRandom, uLandObjects, uIO, uLandTexture, sysutils,
-     uVariables, uUtils;
+     uVariables, uUtils, uCommands, Adler32;
 
 operator=(const a, b: direction) c: Boolean;
 begin
@@ -1294,8 +1294,35 @@
     GenPreview:= Preview
 end;
 
+
+procedure chLandCheck(var s: shortstring);
+begin
+{$IFDEF DEBUGFILE}
+    AddFileLog('CheckLandDigest: ' + s + ' digest : ' + digest);
+{$ENDIF}
+    if digest = '' then
+        digest:= s
+    else
+        TryDo(s = digest, 'Different maps generated, sorry', true);
+end;
+
+procedure chSendLandDigest(var s: shortstring);
+var adler, i: LongInt;
+begin
+    adler:= 1;
+    for i:= 0 to LAND_HEIGHT-1 do
+        Adler32Update(adler, @Land[i,0], LAND_WIDTH);
+    s:= 'M' + IntToStr(adler);
+
+    chLandCheck(s);
+    SendIPCRaw(@s[0], Length(s) + 1)
+end;
+
 procedure initModule;
 begin
+    RegisterVariable('landcheck', vtCommand, @chLandCheck, false);
+    RegisterVariable('sendlanddigest', vtCommand, @chSendLandDigest, false);
+
     LandBackSurface:= nil;
     digest:= '';
 
--- a/hedgewars/uSound.pas	Sun Nov 21 09:37:48 2010 -0500
+++ b/hedgewars/uSound.pas	Sun Nov 21 17:48:58 2010 +0300
@@ -46,7 +46,7 @@
 
 
 implementation
-uses uMisc, uVariables, uConsole, uUtils, uIO;
+uses uMisc, uVariables, uConsole, uUtils, uIO, uCommands;
 
 const chanTPU = 32;
 var Volume: LongInt;
@@ -317,8 +317,17 @@
     Mix_ResumeMusic(Mus);
 end;
 
+procedure chVoicepack(var s: shortstring);
+begin
+    if CurrentTeam = nil then OutError(errmsgIncorrectUse + ' "/voicepack"', true);
+    if s[1]='"' then Delete(s, 1, 1);
+    if s[byte(s[0])]='"' then Delete(s, byte(s[0]), 1);
+    CurrentTeam^.voicepack:= AskForVoicepack(s)
+end;
+
 procedure initModule;
 begin
+    RegisterVariable('voicepack', vtCommand, @chVoicepack, false);
     MusicFN:='';
 end;
 
--- a/hedgewars/uStore.pas	Sun Nov 21 09:37:48 2010 -0500
+++ b/hedgewars/uStore.pas	Sun Nov 21 17:48:58 2010 +0300
@@ -39,7 +39,7 @@
 procedure FreeWeaponTooltip;
 
 implementation
-uses uMisc, uConsole, uMobile, uVariables, uUtils, uTextures, uIO, uRender, uRenderUtils;
+uses uMisc, uConsole, uMobile, uVariables, uUtils, uTextures, uIO, uRender, uRenderUtils, uCommands;
 
 type TGPUVendor = (gvUnknown, gvNVIDIA, gvATI, gvIntel, gvApple);
 
@@ -778,8 +778,85 @@
 WeaponTooltipTex:= nil
 end;
 
+procedure chFullScr(var s: shortstring);
+var flags: Longword = 0;
+    ico: PSDL_Surface;
+{$IFDEF DEBUGFILE}
+    buf: array[byte] of char;
+{$ENDIF}
+begin
+    s:= s; // avoid compiler hint
+    if Length(s) = 0 then cFullScreen:= not cFullScreen
+    else cFullScreen:= s = '1';
+
+{$IFDEF DEBUGFILE}
+    buf[0]:= char(0); // avoid compiler hint
+    AddFileLog('Prepare to change video parameters...');
+{$ENDIF}
+
+    flags:= SDL_OPENGL;// or SDL_RESIZABLE;
+
+    if cFullScreen then
+        flags:= flags or SDL_FULLSCREEN;
+
+{$IFDEF SDL_IMAGE_NEWER}
+    WriteToConsole('Init SDL_image... ');
+    SDLTry(IMG_Init(IMG_INIT_PNG) <> 0, true);
+    WriteLnToConsole(msgOK);
+{$ENDIF}
+    // load engine icon
+{$IFDEF DARWIN}
+    ico:= LoadImage(Pathz[ptGraphics] + '/hwengine_mac', ifIgnoreCaps);
+{$ELSE}
+    ico:= LoadImage(Pathz[ptGraphics] + '/hwengine', ifIgnoreCaps);
+{$ENDIF}
+    if ico <> nil then
+    begin
+        SDL_WM_SetIcon(ico, 0);
+        SDL_FreeSurface(ico)
+    end;
+
+    // set window caption
+    SDL_WM_SetCaption('Hedgewars', nil);
+
+    if SDLPrimSurface <> nil then
+    begin
+{$IFDEF DEBUGFILE}
+        AddFileLog('Freeing old primary surface...');
+{$ENDIF}
+        SDL_FreeSurface(SDLPrimSurface);
+        SDLPrimSurface:= nil;
+    end;
+
+{$IFDEF SDL13}
+    if SDLwindow = nil then
+    begin
+        SDLwindow:= SDL_CreateWindow('Hedgewars', 0, 0, cScreenWidth, cScreenHeight,
+                        SDL_WINDOW_OPENGL or SDL_WINDOW_SHOWN
+                        {$IFDEF IPHONEOS} or SDL_WINDOW_BORDERLESS{$ENDIF});
+        SDL_CreateRenderer(SDLwindow, -1, 0);
+    end;
+
+    SDL_SetRenderDrawColor(0, 0, 0, 255);
+    SDL_RenderFill(nil);
+    SDL_RenderPresent();
+{$ELSE}
+    SDLPrimSurface:= SDL_SetVideoMode(cScreenWidth, cScreenHeight, cBits, flags);
+    SDLTry(SDLPrimSurface <> nil, true);
+    PixelFormat:= SDLPrimSurface^.format;
+{$ENDIF}
+
+{$IFDEF DEBUGFILE}
+    AddFileLog('Setting up OpenGL...');
+    AddFileLog('SDL video driver: ' + shortstring(SDL_VideoDriverName(buf, sizeof(buf))));
+{$ENDIF}
+    SetupOpenGL();
+end;
+
 procedure initModule;
 begin
+    RegisterVariable('fullscr', vtCommand, @chFullScr, true);
+
     PixelFormat:= nil;
     SDLPrimSurface:= nil;
 
--- a/hedgewars/uTeams.pas	Sun Nov 21 09:37:48 2010 -0500
+++ b/hedgewars/uTeams.pas	Sun Nov 21 17:48:58 2010 +0300
@@ -24,6 +24,7 @@
 
 procedure initModule;
 procedure freeModule;
+
 function  AddTeam(TeamColor: Longword): PTeam;
 procedure SwitchHedgehog;
 procedure AfterSwitchHedgehog;
@@ -37,7 +38,7 @@
 function  GetTeamStatString(p: PTeam): shortstring;
 
 implementation
-uses uLocale, uAmmos, uChat, uMobile, uVariables, uUtils, uIO, uCaptions;
+uses uLocale, uAmmos, uChat, uMobile, uVariables, uUtils, uIO, uCaptions, uCommands;
 
 const MaxTeamHealth: LongInt = 0;
 
@@ -431,8 +432,81 @@
     GetTeamStatString:= s;
 end;
 
+procedure chAddHH(var id: shortstring);
+var s: shortstring;
+    Gear: PGear;
+begin
+    s:= '';
+    if (not isDeveloperMode) or (CurrentTeam = nil) then exit;
+    with CurrentTeam^ do
+        begin
+        SplitBySpace(id, s);
+        CurrentHedgehog:= @Hedgehogs[HedgehogsNumber];
+        val(id, CurrentHedgehog^.BotLevel);
+        Gear:= AddGear(0, 0, gtHedgehog, 0, _0, _0, 0);
+        SplitBySpace(s, id);
+        val(s, Gear^.Health);
+        TryDo(Gear^.Health > 0, 'Invalid hedgehog health', true);
+        Gear^.Hedgehog^.Team:= CurrentTeam;
+        if (GameFlags and gfSharedAmmo) <> 0 then CurrentHedgehog^.AmmoStore:= Clan^.ClanIndex
+        else if (GameFlags and gfPerHogAmmo) <> 0 then
+            begin
+            AddAmmoStore;
+            CurrentHedgehog^.AmmoStore:= StoreCnt - 1
+            end
+        else CurrentHedgehog^.AmmoStore:= TeamsCount - 1;
+        CurrentHedgehog^.Gear:= Gear;
+        CurrentHedgehog^.Name:= id;
+        CurrentHedgehog^.InitialHealth:= Gear^.Health;
+        CurrHedgehog:= HedgehogsNumber;
+        inc(HedgehogsNumber)
+        end
+end;
+
+procedure chAddTeam(var s: shortstring);
+var Color: Longword;
+    ts, cs: shortstring;
+begin
+    cs:= '';
+    ts:= '';
+    if isDeveloperMode then
+        begin
+        SplitBySpace(s, cs);
+        SplitBySpace(cs, ts);
+        val(cs, Color);
+        TryDo(Color <> 0, 'Error: black team color', true);
+
+        // color is always little endian so the mask must be constant also in big endian archs
+        Color:= Color or $FF000000;
+
+        AddTeam(Color);
+        CurrentTeam^.TeamName:= ts;
+        CurrentTeam^.PlayerHash:= s;
+        if GameType in [gmtDemo, gmtSave] then CurrentTeam^.ExtDriven:= true;
+
+        CurrentTeam^.voicepack:= AskForVoicepack('Default')
+        end
+end;
+
+procedure chSetHHCoords(var x: shortstring);
+var y: shortstring;
+    t: Longint;
+begin
+y:= '';
+if (not isDeveloperMode) or (CurrentHedgehog = nil) or (CurrentHedgehog^.Gear = nil) then exit;
+SplitBySpace(x, y);
+val(x, t);
+CurrentHedgehog^.Gear^.X:= int2hwFloat(t);
+val(y, t);
+CurrentHedgehog^.Gear^.Y:= int2hwFloat(t)
+end;
+
 procedure initModule;
 begin
+    RegisterVariable('addhh', vtCommand, @chAddHH, false);
+    RegisterVariable('addteam', vtCommand, @chAddTeam, false);
+    RegisterVariable('hhcoords', vtCommand, @chSetHHCoords  , false);
+
     CurrentTeam:= nil;
     PreviousTeam:= nil;
     CurrentHedgehog:= nil;
--- a/hedgewars/uUtils.pas	Sun Nov 21 09:37:48 2010 -0500
+++ b/hedgewars/uUtils.pas	Sun Nov 21 17:48:58 2010 +0300
@@ -38,6 +38,8 @@
 procedure AddFileLog(s: shortstring);
 {$ENDIF}
 
+function CheckNoTeamOrHH: boolean; inline;
+
 procedure initModule;
 procedure freeModule;
 
@@ -284,6 +286,11 @@
         GetLaunchY:= 0
 end;
 
+function CheckNoTeamOrHH: boolean;
+var bRes: boolean;
+begin
+CheckNoTeamOrHH:= (CurrentTeam = nil) or (CurrentHedgehog^.Gear = nil);
+end;
 
 procedure initModule;
 {$IFDEF DEBUGFILE}{$IFNDEF IPHONEOS}var i: LongInt;{$ENDIF}{$ENDIF}