hedgewars/CCHandlers.inc
branchexperimental3D
changeset 4812 f924be23ffb4
parent 4347 0ddb100fea61
parent 4811 3edc0cdcfe03
child 4814 e19791f08443
equal deleted inserted replaced
4347:0ddb100fea61 4812:f924be23ffb4
     1 (*
       
     2 * Hedgewars, a free turn based strategy game
       
     3 * Copyright (c) 2004-2010 Andrey Korotaev <unC0Rr@gmail.com>
       
     4 *
       
     5 * This program is free software; you can redistribute it and/or modify
       
     6 * it under the terms of the GNU General Public License as published by
       
     7 * the Free Software Foundation; version 2 of the License
       
     8 *
       
     9 * This program is distributed in the hope that it will be useful,
       
    10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12 * GNU General Public License for more details.
       
    13 *
       
    14 * You should have received a copy of the GNU General Public License
       
    15 * along with this program; if not, write to the Free Software
       
    16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
       
    17 *)
       
    18 
       
    19 function CheckNoTeamOrHH: boolean;
       
    20 var bRes: boolean;
       
    21 begin
       
    22 bRes:= (CurrentTeam = nil) or (CurrentHedgehog^.Gear = nil);
       
    23 {$IFDEF DEBUGFILE}
       
    24 if bRes then
       
    25 if CurrentTeam = nil then AddFileLog('CONSOLE: CurTeam = nil')
       
    26                         else AddFileLog('CONSOLE: CurTeam <> nil, Gear = nil');
       
    27 {$ENDIF}
       
    28 CheckNoTeamOrHH:= bRes;
       
    29 end;
       
    30 ////////////////////////////////////////////////////////////////////////////////
       
    31 procedure chQuit(var s: shortstring);
       
    32 const prevGState: TGameState = gsConfirm;
       
    33 begin
       
    34 s:= s; // avoid compiler hint
       
    35 if GameState <> gsConfirm then
       
    36         begin
       
    37         prevGState:= GameState;
       
    38         GameState:= gsConfirm
       
    39         end else
       
    40         GameState:= prevGState
       
    41 end;
       
    42 
       
    43 procedure chConfirm(var s: shortstring);
       
    44 begin
       
    45 s:= s; // avoid compiler hint
       
    46 if GameState = gsConfirm then
       
    47     begin
       
    48     SendIPC('Q');
       
    49     GameState:= gsExit
       
    50     end
       
    51 else
       
    52     begin
       
    53     GameState:= gsChat;
       
    54     KeyPressChat(27);
       
    55     KeyPressChat(47);
       
    56     KeyPressChat(116);
       
    57     KeyPressChat(101);
       
    58     KeyPressChat(97);
       
    59     KeyPressChat(109);
       
    60     KeyPressChat(32)
       
    61     end
       
    62 end;
       
    63 
       
    64 procedure chCheckProto(var s: shortstring);
       
    65 var i, c: LongInt;
       
    66 begin
       
    67 if isDeveloperMode then
       
    68 begin
       
    69 val(s, i, c);
       
    70 if (c <> 0) or (i = 0) then exit;
       
    71 TryDo(i <= cNetProtoVersion, 'Protocol version mismatch: engine is too old', true);
       
    72 TryDo(i >= cNetProtoVersion, 'Protocol version mismatch: engine is too new', true)
       
    73 end
       
    74 end;
       
    75 
       
    76 procedure chAddTeam(var s: shortstring);
       
    77 var Color: Longword;
       
    78     ts, cs: shortstring;
       
    79 begin
       
    80 cs:= '';
       
    81 ts:= '';
       
    82 if isDeveloperMode then
       
    83 begin
       
    84 SplitBySpace(s, cs);
       
    85 SplitBySpace(cs, ts);
       
    86 val(cs, Color);
       
    87 TryDo(Color <> 0, 'Error: black team color', true);
       
    88 
       
    89 // color is always little endian so the mask must be constant also in big endian archs
       
    90 Color:= Color or $FF000000;
       
    91     
       
    92 AddTeam(Color);
       
    93 CurrentTeam^.TeamName:= ts;
       
    94 CurrentTeam^.PlayerHash:= s;
       
    95 if GameType in [gmtDemo, gmtSave] then CurrentTeam^.ExtDriven:= true;
       
    96 
       
    97 CurrentTeam^.voicepack:= AskForVoicepack('Default')
       
    98 end
       
    99 end;
       
   100 
       
   101 procedure chTeamLocal(var s: shortstring);
       
   102 begin
       
   103 s:= s; // avoid compiler hint
       
   104 if not isDeveloperMode then exit;
       
   105 if CurrentTeam = nil then OutError(errmsgIncorrectUse + ' "/rdriven"', true);
       
   106 CurrentTeam^.ExtDriven:= true
       
   107 end;
       
   108 
       
   109 procedure chGrave(var s: shortstring);
       
   110 begin
       
   111 if CurrentTeam = nil then OutError(errmsgIncorrectUse + ' "/grave"', true);
       
   112 if s[1]='"' then Delete(s, 1, 1);
       
   113 if s[byte(s[0])]='"' then Delete(s, byte(s[0]), 1);
       
   114 CurrentTeam^.GraveName:= s
       
   115 end;
       
   116 
       
   117 procedure chFort(var s: shortstring);
       
   118 begin
       
   119 if CurrentTeam = nil then OutError(errmsgIncorrectUse + ' "/fort"', true);
       
   120 if s[1]='"' then Delete(s, 1, 1);
       
   121 if s[byte(s[0])]='"' then Delete(s, byte(s[0]), 1);
       
   122 CurrentTeam^.FortName:= s
       
   123 end;
       
   124 
       
   125 procedure chVoicepack(var s: shortstring);
       
   126 begin
       
   127 if CurrentTeam = nil then OutError(errmsgIncorrectUse + ' "/voicepack"', true);
       
   128 if s[1]='"' then Delete(s, 1, 1);
       
   129 if s[byte(s[0])]='"' then Delete(s, byte(s[0]), 1);
       
   130 CurrentTeam^.voicepack:= AskForVoicepack(s)
       
   131 end;
       
   132 
       
   133 procedure chFlag(var s: shortstring);
       
   134 begin
       
   135 if CurrentTeam = nil then OutError(errmsgIncorrectUse + ' "/flag"', true);
       
   136 if s[1]='"' then Delete(s, 1, 1);
       
   137 if s[byte(s[0])]='"' then Delete(s, byte(s[0]), 1);
       
   138 CurrentTeam^.flag:= s
       
   139 end;
       
   140 
       
   141 procedure chScript(var s: shortstring);
       
   142 begin
       
   143 if s[1]='"' then Delete(s, 1, 1);
       
   144 if s[byte(s[0])]='"' then Delete(s, byte(s[0]), 1);
       
   145 ScriptLoad(s)
       
   146 end;
       
   147 
       
   148 procedure chAddHH(var id: shortstring);
       
   149 var s: shortstring;
       
   150     Gear: PGear;
       
   151 begin
       
   152 s:= '';
       
   153 if (not isDeveloperMode) or (CurrentTeam = nil) then exit;
       
   154 with CurrentTeam^ do
       
   155     begin
       
   156     SplitBySpace(id, s);
       
   157     CurrentHedgehog:= @Hedgehogs[HedgehogsNumber];
       
   158     val(id, CurrentHedgehog^.BotLevel);
       
   159     Gear:= AddGear(0, 0, gtHedgehog, 0, _0, _0, 0);
       
   160     SplitBySpace(s, id);
       
   161     val(s, Gear^.Health);
       
   162     TryDo(Gear^.Health > 0, 'Invalid hedgehog health', true);
       
   163     PHedgehog(Gear^.Hedgehog)^.Team:= CurrentTeam;
       
   164     if (GameFlags and gfSharedAmmo) <> 0 then CurrentHedgehog^.AmmoStore:= Clan^.ClanIndex
       
   165     else if (GameFlags and gfPerHogAmmo) <> 0 then
       
   166         begin
       
   167         AddAmmoStore;
       
   168         CurrentHedgehog^.AmmoStore:= StoreCnt - 1
       
   169         end
       
   170     else CurrentHedgehog^.AmmoStore:= TeamsCount - 1;
       
   171     CurrentHedgehog^.Gear:= Gear;
       
   172     CurrentHedgehog^.Name:= id;
       
   173     CurrentHedgehog^.InitialHealth:= Gear^.Health;
       
   174     CurrHedgehog:= HedgehogsNumber;
       
   175     inc(HedgehogsNumber)
       
   176     end
       
   177 end;
       
   178 
       
   179 procedure chSetHat(var s: shortstring);
       
   180 begin
       
   181 if (not isDeveloperMode) or (CurrentTeam = nil) then exit;
       
   182 with CurrentTeam^ do
       
   183     begin
       
   184     if not CurrentHedgehog^.King then
       
   185     if (s = '') or 
       
   186         (((GameFlags and gfKing) <> 0) and (s = 'crown')) or
       
   187         ((Length(s) > 39) and (Copy(s,1,8) = 'Reserved') and (Copy(s,9,32) <> PlayerHash)) then
       
   188         CurrentHedgehog^.Hat:= 'NoHat'
       
   189     else
       
   190         CurrentHedgehog^.Hat:= s
       
   191     end;
       
   192 end;
       
   193 
       
   194 procedure chSetHHCoords(var x: shortstring);
       
   195 var y: shortstring;
       
   196     t: Longint;
       
   197 begin
       
   198 y:= '';
       
   199 if (not isDeveloperMode) or (CurrentHedgehog = nil) or (CurrentHedgehog^.Gear = nil) then exit;
       
   200 SplitBySpace(x, y);
       
   201 val(x, t);
       
   202 CurrentHedgehog^.Gear^.X:= int2hwFloat(t);
       
   203 val(y, t);
       
   204 CurrentHedgehog^.Gear^.Y:= int2hwFloat(t)
       
   205 end;
       
   206 
       
   207 procedure chSetAmmoLoadout(var descr: shortstring);
       
   208 begin
       
   209 SetAmmoLoadout(descr)
       
   210 end;
       
   211 
       
   212 procedure chSetAmmoDelay(var descr: shortstring);
       
   213 begin
       
   214 SetAmmoDelay(descr)
       
   215 end;
       
   216 
       
   217 procedure chSetAmmoProbability(var descr: shortstring);
       
   218 begin
       
   219 SetAmmoProbability(descr)
       
   220 end;
       
   221 
       
   222 procedure chSetAmmoReinforcement(var descr: shortstring);
       
   223 begin
       
   224 SetAmmoReinforcement(descr)
       
   225 end;
       
   226 
       
   227 procedure chAddAmmoStore(var descr: shortstring);
       
   228 begin
       
   229 descr:= ''; // avoid compiler hint
       
   230 AddAmmoStore
       
   231 end;
       
   232 
       
   233 procedure chBind(var id: shortstring);
       
   234 var s: shortstring;
       
   235     b: LongInt;
       
   236 begin
       
   237 s:= '';
       
   238 if CurrentTeam = nil then exit;
       
   239 SplitBySpace(id, s);
       
   240 if s[1]='"' then Delete(s, 1, 1);
       
   241 if s[byte(s[0])]='"' then Delete(s, byte(s[0]), 1);
       
   242 b:= KeyNameToCode(id);
       
   243 if b = 0 then OutError(errmsgUnknownVariable + ' "' + id + '"', false)
       
   244         else CurrentTeam^.Binds[b]:= s
       
   245 end;
       
   246 
       
   247 procedure chCurU_p(var s: shortstring);
       
   248 begin
       
   249 s:= s; // avoid compiler hint
       
   250 CursorMovementY:= -1;
       
   251 end;
       
   252 
       
   253 procedure chCurU_m(var s: shortstring);
       
   254 begin
       
   255 s:= s; // avoid compiler hint
       
   256 CursorMovementY:= 0;
       
   257 end;
       
   258 
       
   259 procedure chCurD_p(var s: shortstring);
       
   260 begin
       
   261 s:= s; // avoid compiler hint
       
   262 CursorMovementY:= 1;
       
   263 end;
       
   264 
       
   265 procedure chCurD_m(var s: shortstring);
       
   266 begin
       
   267 s:= s; // avoid compiler hint
       
   268 CursorMovementY:= 0;
       
   269 end;
       
   270 
       
   271 procedure chCurL_p(var s: shortstring);
       
   272 begin
       
   273 s:= s; // avoid compiler hint
       
   274 CursorMovementX:= -1;
       
   275 end;
       
   276 
       
   277 procedure chCurL_m(var s: shortstring);
       
   278 begin
       
   279 s:= s; // avoid compiler hint
       
   280 CursorMovementX:= 0;
       
   281 end;
       
   282 
       
   283 procedure chCurR_p(var s: shortstring);
       
   284 begin
       
   285 s:= s; // avoid compiler hint
       
   286 CursorMovementX:= 1;
       
   287 end;
       
   288 
       
   289 procedure chCurR_m(var s: shortstring);
       
   290 begin
       
   291 s:= s; // avoid compiler hint
       
   292 CursorMovementX:= 0;
       
   293 end;
       
   294 
       
   295 procedure chLeft_p(var s: shortstring);
       
   296 begin
       
   297 s:= s; // avoid compiler hint
       
   298 if CheckNoTeamOrHH or isPaused then exit;
       
   299 if not CurrentTeam^.ExtDriven then SendIPC('L');
       
   300 if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1;
       
   301 bShowFinger:= false;
       
   302 with CurrentHedgehog^.Gear^ do
       
   303     Message:= Message or gmLeft
       
   304 end;
       
   305 
       
   306 procedure chLeft_m(var s: shortstring);
       
   307 begin
       
   308 s:= s; // avoid compiler hint
       
   309 if CheckNoTeamOrHH then exit;
       
   310 if not CurrentTeam^.ExtDriven then SendIPC('l');
       
   311 with CurrentHedgehog^.Gear^ do
       
   312     Message:= Message and not gmLeft
       
   313 end;
       
   314 
       
   315 procedure chRight_p(var s: shortstring);
       
   316 begin
       
   317 s:= s; // avoid compiler hint
       
   318 if CheckNoTeamOrHH or isPaused then exit;
       
   319 if not CurrentTeam^.ExtDriven then SendIPC('R');
       
   320 if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1;
       
   321 bShowFinger:= false;
       
   322 with CurrentHedgehog^.Gear^ do
       
   323     Message:= Message or gmRight
       
   324 end;
       
   325 
       
   326 procedure chRight_m(var s: shortstring);
       
   327 begin
       
   328 s:= s; // avoid compiler hint
       
   329 if CheckNoTeamOrHH then exit;
       
   330 if not CurrentTeam^.ExtDriven then SendIPC('r');
       
   331 with CurrentHedgehog^.Gear^ do
       
   332     Message:= Message and not gmRight
       
   333 end;
       
   334 
       
   335 procedure chUp_p(var s: shortstring);
       
   336 begin
       
   337 s:= s; // avoid compiler hint
       
   338 if CheckNoTeamOrHH or isPaused then exit;
       
   339 if not CurrentTeam^.ExtDriven then SendIPC('U');
       
   340 if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1;
       
   341 bShowFinger:= false;
       
   342 with CurrentHedgehog^.Gear^ do
       
   343     Message:= Message or gmUp
       
   344 end;
       
   345 
       
   346 procedure chUp_m(var s: shortstring);
       
   347 begin
       
   348 s:= s; // avoid compiler hint
       
   349 if CheckNoTeamOrHH then exit;
       
   350 if not CurrentTeam^.ExtDriven then SendIPC('u');
       
   351 with CurrentHedgehog^.Gear^ do
       
   352     Message:= Message and not gmUp
       
   353 end;
       
   354 
       
   355 procedure chDown_p(var s: shortstring);
       
   356 begin
       
   357 s:= s; // avoid compiler hint
       
   358 if CheckNoTeamOrHH or isPaused then exit;
       
   359 if not CurrentTeam^.ExtDriven then SendIPC('D');
       
   360 if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1;
       
   361 bShowFinger:= false;
       
   362 with CurrentHedgehog^.Gear^ do
       
   363     Message:= Message or gmDown
       
   364 end;
       
   365 
       
   366 procedure chDown_m(var s: shortstring);
       
   367 begin
       
   368 s:= s; // avoid compiler hint
       
   369 if CheckNoTeamOrHH then exit;
       
   370 if not CurrentTeam^.ExtDriven then SendIPC('d');
       
   371 with CurrentHedgehog^.Gear^ do
       
   372     Message:= Message and not gmDown
       
   373 end;
       
   374 
       
   375 procedure chPrecise_p(var s: shortstring);
       
   376 begin
       
   377 s:= s; // avoid compiler hint
       
   378 if CheckNoTeamOrHH or isPaused then exit;
       
   379 if not CurrentTeam^.ExtDriven then SendIPC('Z');
       
   380 if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1;
       
   381 bShowFinger:= false;
       
   382 with CurrentHedgehog^.Gear^ do
       
   383     Message:= Message or gmPrecise
       
   384 end;
       
   385 
       
   386 procedure chPrecise_m(var s: shortstring);
       
   387 begin
       
   388 s:= s; // avoid compiler hint
       
   389 if CheckNoTeamOrHH then exit;
       
   390 if not CurrentTeam^.ExtDriven then SendIPC('z');
       
   391 with CurrentHedgehog^.Gear^ do
       
   392     Message:= Message and not gmPrecise
       
   393 end;
       
   394 
       
   395 procedure chLJump(var s: shortstring);
       
   396 begin
       
   397 s:= s; // avoid compiler hint
       
   398 if CheckNoTeamOrHH or isPaused then exit;
       
   399 if not CurrentTeam^.ExtDriven then SendIPC('j');
       
   400 if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1;
       
   401 bShowFinger:= false;
       
   402 with CurrentHedgehog^.Gear^ do
       
   403     Message:= Message or gmLJump
       
   404 end;
       
   405 
       
   406 procedure chHJump(var s: shortstring);
       
   407 begin
       
   408 s:= s; // avoid compiler hint
       
   409 if CheckNoTeamOrHH or isPaused then exit;
       
   410 if not CurrentTeam^.ExtDriven then SendIPC('J');
       
   411 if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1;
       
   412 bShowFinger:= false;
       
   413 with CurrentHedgehog^.Gear^ do
       
   414     Message:= Message or gmHJump
       
   415 end;
       
   416 
       
   417 procedure chAttack_p(var s: shortstring);
       
   418 begin
       
   419 s:= s; // avoid compiler hint
       
   420 if CheckNoTeamOrHH or isPaused then exit;
       
   421 if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1;
       
   422 bShowFinger:= false;
       
   423 with CurrentHedgehog^.Gear^ do
       
   424     begin
       
   425     {$IFDEF DEBUGFILE}AddFileLog('/+attack: hedgehog''s Gear^.State = '+inttostr(State));{$ENDIF}
       
   426     if ((State and gstHHDriven) <> 0) then
       
   427         begin
       
   428         FollowGear:= CurrentHedgehog^.Gear;
       
   429         if not CurrentTeam^.ExtDriven then SendIPC('A');
       
   430         Message:= Message or gmAttack
       
   431         end
       
   432     end
       
   433 end;
       
   434 
       
   435 procedure chAttack_m(var s: shortstring);
       
   436 begin
       
   437 s:= s; // avoid compiler hint
       
   438 if CheckNoTeamOrHH then exit;
       
   439 with CurrentHedgehog^.Gear^ do
       
   440     begin
       
   441     if not CurrentTeam^.ExtDriven and
       
   442         ((Message and gmAttack) <> 0) then SendIPC('a');
       
   443     Message:= Message and not gmAttack
       
   444     end
       
   445 end;
       
   446 
       
   447 procedure chSwitch(var s: shortstring);
       
   448 begin
       
   449 s:= s; // avoid compiler hint
       
   450 if CheckNoTeamOrHH or isPaused then exit;
       
   451 if not CurrentTeam^.ExtDriven then SendIPC('S');
       
   452 if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1;
       
   453 bShowFinger:= false;
       
   454 with CurrentHedgehog^.Gear^ do
       
   455     Message:= Message or gmSwitch
       
   456 end;
       
   457 
       
   458 procedure chNextTurn(var s: shortstring);
       
   459 begin
       
   460     s:= s; // avoid compiler hint
       
   461     TryDo(AllInactive, '/nextturn called when not all gears are inactive', true);
       
   462 
       
   463     if not CurrentTeam^.ExtDriven then SendIPC('N');
       
   464 {$IFDEF DEBUGFILE}
       
   465     AddFileLog('Doing SwitchHedgehog: time '+inttostr(GameTicks));
       
   466 {$ENDIF}
       
   467     perfExt_NewTurnBeginning();
       
   468 end;
       
   469 
       
   470 procedure chSay(var s: shortstring);
       
   471 begin
       
   472 SendIPC('s' + s);
       
   473 
       
   474 if copy(s, 1, 4) = '/me ' then
       
   475     s:= #2'* ' + UserNick + ' ' + copy(s, 5, Length(s) - 4)
       
   476 else
       
   477     s:= #1 + UserNick + ': ' + s;
       
   478 
       
   479 AddChatString(s)
       
   480 end;
       
   481 
       
   482 procedure chTeamSay(var s: shortstring);
       
   483 begin
       
   484 SendIPC('b' + s);
       
   485 
       
   486 s:= #4 + '[Team] ' + UserNick + ': ' + s;
       
   487 
       
   488 AddChatString(s)
       
   489 end;
       
   490 
       
   491 procedure chTimer(var s: shortstring);
       
   492 begin
       
   493 if (s[0] <> #1) or (s[1] < '1') or (s[1] > '5') or CheckNoTeamOrHH then exit;
       
   494 
       
   495 if not CurrentTeam^.ExtDriven then SendIPC(s);
       
   496 if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1;
       
   497 bShowFinger:= false;
       
   498 with CurrentHedgehog^.Gear^ do
       
   499     begin
       
   500     Message:= Message or gmTimer;
       
   501     MsgParam:= byte(s[1]) - ord('0')
       
   502     end
       
   503 end;
       
   504 
       
   505 procedure chSlot(var s: shortstring);
       
   506 var slot: LongWord;
       
   507 begin
       
   508 if (s[0] <> #1) or CheckNoTeamOrHH then exit;
       
   509 slot:= byte(s[1]) - 49;
       
   510 if slot > cMaxSlotIndex then exit;
       
   511 if not CurrentTeam^.ExtDriven then SendIPC(char(byte(s[1]) + 79));
       
   512 if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1;
       
   513 bShowFinger:= false;
       
   514 with CurrentHedgehog^.Gear^ do
       
   515     begin
       
   516     Message:= Message or gmSlot;
       
   517     MsgParam:= slot
       
   518     end
       
   519 end;
       
   520 
       
   521 procedure chSetWeapon(var s: shortstring);
       
   522 begin
       
   523     if (s[0] <> #1) or CheckNoTeamOrHH then exit;
       
   524 
       
   525     if TAmmoType(s[1]) > High(TAmmoType) then exit;
       
   526 
       
   527     if not CurrentTeam^.ExtDriven then SendIPC('w' + s);
       
   528 
       
   529     with CurrentHedgehog^.Gear^ do
       
   530     begin
       
   531         Message:= Message or gmWeapon;
       
   532         MsgParam:= byte(s[1]);
       
   533     end;
       
   534 end;
       
   535 
       
   536 procedure chTaunt(var s: shortstring);
       
   537 begin
       
   538 if (s[0] <> #1) or CheckNoTeamOrHH then exit;
       
   539 
       
   540 if TWave(s[1]) > High(TWave) then exit;
       
   541 
       
   542 if not CurrentTeam^.ExtDriven then SendIPC('t' + s);
       
   543 
       
   544 with CurrentHedgehog^.Gear^ do
       
   545     begin
       
   546     Message:= Message or gmAnimate;
       
   547     MsgParam:= byte(s[1])
       
   548     end
       
   549 end;
       
   550 
       
   551 procedure chHogSay(var s: shortstring);
       
   552 var Gear: PVisualGear;
       
   553     text: shortstring;
       
   554 begin
       
   555 text:= copy(s, 2, Length(s)-1);
       
   556 if CheckNoTeamOrHH
       
   557 or ((CurrentHedgehog^.Gear^.State and gstHHDriven) = 0) then
       
   558     begin
       
   559     chSay(text);
       
   560     exit
       
   561     end;
       
   562 
       
   563 if not CurrentTeam^.ExtDriven then SendIPC('h' + s);
       
   564 
       
   565 if byte(s[1]) < 4 then
       
   566     begin
       
   567     Gear:= AddVisualGear(0, 0, vgtSpeechBubble);
       
   568     if Gear <> nil then
       
   569     begin
       
   570     Gear^.Hedgehog:= CurrentHedgehog;
       
   571     Gear^.Text:= text;
       
   572     Gear^.FrameTicks:= byte(s[1])
       
   573     end
       
   574     end
       
   575 else
       
   576     begin
       
   577     SpeechType:= byte(s[1])-3;
       
   578     SpeechText:= text
       
   579     end;
       
   580 
       
   581 end;
       
   582 
       
   583 procedure doPut(putX, putY: LongInt; fromAI: boolean);
       
   584 begin
       
   585 if CheckNoTeamOrHH or isPaused then exit;
       
   586 if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1;
       
   587 bShowFinger:= false;
       
   588 if not CurrentTeam^.ExtDriven and bShowAmmoMenu then
       
   589     begin
       
   590     bSelected:= true;
       
   591     exit
       
   592     end;
       
   593 
       
   594 with CurrentHedgehog^.Gear^,
       
   595     CurrentHedgehog^ do
       
   596     if (State and gstHHChooseTarget) <> 0 then
       
   597         begin
       
   598         isCursorVisible:= false;
       
   599         if not CurrentTeam^.ExtDriven then
       
   600             begin
       
   601             if fromAI then
       
   602                 begin
       
   603                 TargetPoint.X:= putX;
       
   604                 TargetPoint.Y:= putY
       
   605                 end else
       
   606                 begin
       
   607                 TargetPoint.X:= CursorPoint.X - WorldDx;
       
   608                 TargetPoint.Y:= cScreenHeight - CursorPoint.Y - WorldDy;
       
   609                 end;
       
   610             SendIPCXY('p', TargetPoint.X, TargetPoint.Y);
       
   611             end
       
   612         else
       
   613             begin
       
   614             TargetPoint.X:= putX;
       
   615             TargetPoint.Y:= putY
       
   616             end;
       
   617         {$IFDEF DEBUGFILE}AddFilelog('put: ' + inttostr(TargetPoint.X) + ', ' + inttostr(TargetPoint.Y));{$ENDIF}
       
   618         State:= State and not gstHHChooseTarget;
       
   619         if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackingPut) <> 0 then
       
   620             Message:= Message or gmAttack;
       
   621         end
       
   622     else
       
   623         if CurrentTeam^.ExtDriven then
       
   624             OutError('got /put while not being in choose target mode', false)
       
   625 end;
       
   626 
       
   627 procedure chPut(var s: shortstring);
       
   628 begin
       
   629     s:= s; // avoid compiler hint
       
   630     doPut(0, 0, false);
       
   631 end;
       
   632 
       
   633 procedure chCapture(var s: shortstring);
       
   634 begin
       
   635 s:= s; // avoid compiler hint
       
   636 flagMakeCapture:= true
       
   637 end;
       
   638 
       
   639 procedure chSkip(var s: shortstring);
       
   640 begin
       
   641 s:= s; // avoid compiler hint
       
   642 if not CurrentTeam^.ExtDriven then SendIPC(',');
       
   643 uStats.Skipped;
       
   644 skipFlag:= true
       
   645 end;
       
   646 
       
   647 procedure chSetMap(var s: shortstring);
       
   648 begin
       
   649 if isDeveloperMode then
       
   650 begin
       
   651 Pathz[ptMapCurrent]:= Pathz[ptMaps] + '/' + s;
       
   652 InitStepsFlags:= InitStepsFlags or cifMap
       
   653 end
       
   654 end;
       
   655 
       
   656 procedure chSetTheme(var s: shortstring);
       
   657 begin
       
   658 if isDeveloperMode then
       
   659 begin
       
   660 Pathz[ptCurrTheme]:= Pathz[ptThemes] + '/' + s;
       
   661 InitStepsFlags:= InitStepsFlags or cifTheme
       
   662 end
       
   663 end;
       
   664 
       
   665 procedure chSetSeed(var s: shortstring);
       
   666 begin
       
   667 if isDeveloperMode then
       
   668 begin
       
   669 SetRandomSeed(s);
       
   670 cSeed:= s;
       
   671 InitStepsFlags:= InitStepsFlags or cifRandomize
       
   672 end
       
   673 end;
       
   674 
       
   675 procedure chAmmoMenu(var s: shortstring);
       
   676 begin
       
   677 s:= s; // avoid compiler hint
       
   678 if CheckNoTeamOrHH then
       
   679     bShowAmmoMenu:= true
       
   680 else
       
   681     begin
       
   682     with CurrentTeam^ do
       
   683         with Hedgehogs[CurrHedgehog] do
       
   684             begin
       
   685             bSelected:= false;
       
   686 
       
   687             if bShowAmmoMenu then bShowAmmoMenu:= false
       
   688             else if ((Gear^.State and (gstAttacking or gstAttacked)) <> 0) or 
       
   689                     ((MultiShootAttacks > 0) and ((Ammoz[CurAmmoType].Ammo.Propz and ammoprop_NoRoundEnd) = 0)) or
       
   690                     ((Gear^.State and gstHHDriven) = 0) then else bShowAmmoMenu:= true
       
   691             end;
       
   692     if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1
       
   693     end
       
   694 end;
       
   695 
       
   696 procedure chFullScr(var s: shortstring);
       
   697 var flags: Longword = 0;
       
   698     ico: PSDL_Surface;
       
   699 {$IFDEF DEBUGFILE}
       
   700     buf: array[byte] of char;
       
   701 {$ENDIF}
       
   702 begin
       
   703     s:= s; // avoid compiler hint
       
   704     if Length(s) = 0 then cFullScreen:= not cFullScreen
       
   705     else cFullScreen:= s = '1';
       
   706 
       
   707 {$IFDEF DEBUGFILE}
       
   708     buf[0]:= char(0); // avoid compiler hint
       
   709     AddFileLog('Prepare to change video parameters...');
       
   710 {$ENDIF}
       
   711 
       
   712     flags:= SDL_OPENGL;// or SDL_RESIZABLE;
       
   713 
       
   714     if cFullScreen then
       
   715         flags:= flags or SDL_FULLSCREEN;
       
   716 
       
   717 {$IFDEF SDL_IMAGE_NEWER}
       
   718     WriteToConsole('Init SDL_image... ');
       
   719     SDLTry(IMG_Init(IMG_INIT_PNG) <> 0, true);
       
   720     WriteLnToConsole(msgOK);
       
   721 {$ENDIF}
       
   722     // load engine icon
       
   723 {$IFDEF DARWIN}
       
   724     ico:= LoadImage(Pathz[ptGraphics] + '/hwengine_mac', ifIgnoreCaps);
       
   725 {$ELSE}
       
   726     ico:= LoadImage(Pathz[ptGraphics] + '/hwengine', ifIgnoreCaps);
       
   727 {$ENDIF}
       
   728     if ico <> nil then
       
   729     begin
       
   730         SDL_WM_SetIcon(ico, 0);
       
   731         SDL_FreeSurface(ico)
       
   732     end;
       
   733     
       
   734     // set window caption
       
   735     SDL_WM_SetCaption('Hedgewars', nil);
       
   736     
       
   737     if SDLPrimSurface <> nil then
       
   738     begin
       
   739 {$IFDEF DEBUGFILE}
       
   740         AddFileLog('Freeing old primary surface...');
       
   741 {$ENDIF}
       
   742         SDL_FreeSurface(SDLPrimSurface);
       
   743         SDLPrimSurface:= nil;
       
   744     end;
       
   745     
       
   746 {$IFDEF SDL13}
       
   747     if SDLwindow = nil then
       
   748     begin
       
   749         SDLwindow:= SDL_CreateWindow('Hedgewars', 0, 0, cScreenWidth, cScreenHeight,
       
   750                         SDL_WINDOW_OPENGL or SDL_WINDOW_SHOWN    
       
   751                         {$IFDEF IPHONEOS} or SDL_WINDOW_BORDERLESS{$ENDIF});     
       
   752         SDL_CreateRenderer(SDLwindow, -1, 0);
       
   753     end;
       
   754     
       
   755     SDL_SetRenderDrawColor(0, 0, 0, 255);    
       
   756     SDL_RenderFill(nil);     
       
   757     SDL_RenderPresent();
       
   758 {$ELSE}
       
   759     SDLPrimSurface:= SDL_SetVideoMode(cScreenWidth, cScreenHeight, cBits, flags);
       
   760     SDLTry(SDLPrimSurface <> nil, true);
       
   761     PixelFormat:= SDLPrimSurface^.format;
       
   762 {$ENDIF}
       
   763 
       
   764 {$IFDEF DEBUGFILE}
       
   765     AddFileLog('Setting up OpenGL...');
       
   766     AddFileLog('SDL video driver: ' + shortstring(SDL_VideoDriverName(buf, sizeof(buf))));
       
   767 {$ENDIF}
       
   768     SetupOpenGL();
       
   769 end;
       
   770 
       
   771 procedure chVol_p(var s: shortstring);
       
   772 begin
       
   773 s:= s; // avoid compiler hint
       
   774 inc(cVolumeDelta, 3)
       
   775 end;
       
   776 
       
   777 procedure chVol_m(var s: shortstring);
       
   778 begin
       
   779 s:= s; // avoid compiler hint
       
   780 dec(cVolumeDelta, 3)
       
   781 end;
       
   782 
       
   783 procedure chFindhh(var s: shortstring);
       
   784 begin
       
   785 s:= s; // avoid compiler hint
       
   786 if CheckNoTeamOrHH or isPaused then exit;
       
   787 bShowFinger:= true;
       
   788 FollowGear:= CurrentHedgehog^.Gear
       
   789 end;
       
   790 
       
   791 procedure chPause(var s: shortstring);
       
   792 begin
       
   793 s:= s; // avoid compiler hint
       
   794 if ReadyTimeLeft > 1 then ReadyTimeLeft:= 1;
       
   795 if gameType <> gmtNet then
       
   796     isPaused:= not isPaused;
       
   797 SDL_ShowCursor(ord(isPaused))
       
   798 end;
       
   799 
       
   800 procedure chRotateMask(var s: shortstring);
       
   801 begin
       
   802 s:= s; // avoid compiler hint
       
   803 if ((GameFlags and gfInvulnerable) = 0) then cTagsMask:= cTagsMasks[cTagsMask] else cTagsMask:= cTagsMasksNoHealth[cTagsMask];
       
   804 end;
       
   805 
       
   806 procedure chSpeedup_p(var s: shortstring);
       
   807 begin
       
   808 s:= s; // avoid compiler hint
       
   809 isSpeed:= true
       
   810 end;
       
   811 
       
   812 procedure chSpeedup_m(var s: shortstring);
       
   813 begin
       
   814 s:= s; // avoid compiler hint
       
   815 isSpeed:= false
       
   816 end;
       
   817 
       
   818 procedure chZoomIn(var s: shortstring);
       
   819 begin
       
   820     s:= s; // avoid compiler hint
       
   821     if ZoomValue < cMinZoomLevel then
       
   822         ZoomValue:= ZoomValue + cZoomDelta;
       
   823 end;
       
   824 
       
   825 procedure chZoomOut(var s: shortstring);
       
   826 begin
       
   827     s:= s; // avoid compiler hint
       
   828     if ZoomValue > cMaxZoomLevel then
       
   829         ZoomValue:= ZoomValue - cZoomDelta;
       
   830 end;
       
   831 
       
   832 procedure chZoomReset(var s: shortstring);
       
   833 begin
       
   834     s:= s; // avoid compiler hint
       
   835     ZoomValue:= cDefaultZoomLevel;
       
   836 end;
       
   837 
       
   838 procedure chChat(var s: shortstring);
       
   839 begin
       
   840     s:= s; // avoid compiler hint
       
   841     GameState:= gsChat;
       
   842     KeyPressChat(27)
       
   843 end;
       
   844 
       
   845 procedure chHistory(var s: shortstring);
       
   846 begin
       
   847     s:= s; // avoid compiler hint
       
   848     uChat.showAll:= not uChat.showAll
       
   849 end;