DEADSOFTWARE

added player handicap
[d2df-sdl.git] / src / game / g_game.pas
index ad9330d7cdd293233479985cf73ac3852f1f84b2..7a70840b33b47db24b85276e7d1d63f77f1f26e1 100644 (file)
@@ -23,7 +23,7 @@ uses
   MAPDEF,
   g_basic, g_player, e_graphics, g_res_downloader,
   g_sound, g_gui, utils, md5, mempool, xprofiler,
-  g_touch;
+  g_touch, g_weapons;
 
 type
   TGameSettings = record
@@ -325,7 +325,8 @@ var
   gDelayedEvents: Array of TDelayedEvent;
   gUseChatSounds: Boolean = True;
   gChatSounds: Array of TChatSound;
-  gSelectWeapon: Array [0..1] of Integer = (-1, -1); // [player]
+  gSelectWeapon: Array [0..1, WP_FIRST..WP_LAST] of Boolean; // [player, weapon]
+  gInterReadyCount: Integer = 0;
 
   g_dbg_ignore_bounds: Boolean = false;
   r_smallmap_h: Integer = 0; // 0: left; 1: center; 2: right
@@ -373,7 +374,7 @@ uses
 {$ENDIF}
   e_texture, g_textures, g_main, g_window, g_menu,
   e_input, e_log, g_console, g_items, g_map, g_panel,
-  g_playermodel, g_gfx, g_options, g_weapons, Math,
+  g_playermodel, g_gfx, g_options, Math,
   g_triggers, g_monsters, e_sound, CONFIG,
   g_language, g_net,
   ENet, e_msg, g_netmsg, g_netmaster,
@@ -578,6 +579,7 @@ var
   MessageLineLength: Integer = 80;
   MapList: SSArray = nil;
   MapIndex: Integer = -1;
+  InterReadyTime: Integer = -1;
   MegaWAD: record
     info: TMegaWADInfo;
     endpic: String;
@@ -978,6 +980,7 @@ begin
               SetLength(CustomStat.PlayerStat, Length(CustomStat.PlayerStat)+1);
               with CustomStat.PlayerStat[High(CustomStat.PlayerStat)] do
               begin
+                Num := a;
                 Name := gPlayers[a].Name;
                 Frags := gPlayers[a].Frags;
                 Deaths := gPlayers[a].Death;
@@ -992,6 +995,8 @@ begin
         end;
 
         g_Game_ExecuteEvent('onmapend');
+        if not g_Game_IsClient then g_Player_ResetReady;
+        gInterReadyCount := 0;
 
       // Çàòóõàþùèé ýêðàí:
         EndingGameCounter := 255;
@@ -1324,7 +1329,7 @@ begin
     g_Game_SetLoadingText(_lc[I_LOAD_MUSIC], 0, False);
     g_Sound_CreateWADEx('MUSIC_INTERMUS', GameWAD+':MUSIC\INTERMUS', True);
     g_Sound_CreateWADEx('MUSIC_MENU', GameWAD+':MUSIC\MENU', True);
-    g_Sound_CreateWADEx('MUSIC_ROUNDMUS', GameWAD+':MUSIC\ROUNDMUS', True);
+    g_Sound_CreateWADEx('MUSIC_ROUNDMUS', GameWAD+':MUSIC\ROUNDMUS', True, True);
     g_Sound_CreateWADEx('MUSIC_STDENDMUS', GameWAD+':MUSIC\ENDMUS', True);
 
     g_Game_SetLoadingText(_lc[I_LOAD_MENUS], 0, False);
@@ -1504,6 +1509,7 @@ procedure ProcessPlayerControls (plr: TPlayer; p: Integer; var MoveButton: Byte)
   var
     time: Word;
     strafeDir: Byte;
+    i: Integer;
 begin
   if (plr = nil) then exit;
   if (p = 2) then time := 1000 else time := 1;
@@ -1561,10 +1567,16 @@ begin
   if gPlayerAction[p, ACTION_WEAPPREV] then plr.PressKey(KEY_PREVWEAPON);
   if gPlayerAction[p, ACTION_ACTIVATE] then plr.PressKey(KEY_OPEN);
 
-  if gSelectWeapon[p] >= 0 then
+  gPlayerAction[p, ACTION_WEAPNEXT] := False; // HACK, remove after readyweaon&pendinweapon implementation
+  gPlayerAction[p, ACTION_WEAPPREV] := False; // HACK, remove after readyweaon&pendinweapon implementation
+
+  for i := WP_FIRST to WP_LAST do
   begin
-    plr.QueueWeaponSwitch(gSelectWeapon[p]);
-    gSelectWeapon[p] := -1
+    if gSelectWeapon[p, i] then
+    begin
+      plr.QueueWeaponSwitch(i); // all choices are passed there, and god will take the best
+      gSelectWeapon[p, i] := False
+    end
   end;
 
   // HACK: add dynlight here
@@ -1583,6 +1595,14 @@ begin
   if gwin_has_stencil and g_playerLight then g_AddDynLight(plr.GameX+32, plr.GameY+40, 128, 1, 1, 0, 0.6);
 end;
 
+// HACK: don't have a "key was pressed" function
+procedure InterReady();
+begin
+  if InterReadyTime > gTime then Exit;
+  InterReadyTime := gTime + 3000;
+  MC_SEND_CheatRequest(NET_CHEAT_READY);
+end;
+
 procedure g_Game_Update();
 var
   Msg: g_gui.TMessage;
@@ -1668,12 +1688,14 @@ begin
           (
             (
               e_KeyPressed(IK_RETURN) or e_KeyPressed(IK_KPRETURN) or e_KeyPressed(IK_SPACE) or
-              e_KeyPressed(VK_FIRE) or e_KeyPressed(VK_OPEN)
+              e_KeyPressed(VK_FIRE) or e_KeyPressed(VK_OPEN) or
+              e_KeyPressed(JOY0_ATTACK) or e_KeyPressed(JOY1_ATTACK) or
+              e_KeyPressed(JOY2_ATTACK) or e_KeyPressed(JOY3_ATTACK)
             )
             and (not gJustChatted) and (not gConsoleShow) and (not gChatShow)
             and (g_ActiveWindow = nil)
           )
-          or (g_Game_IsNet and (gInterTime > gInterEndTime))
+          or (g_Game_IsNet and ((gInterTime > gInterEndTime) or (gInterReadyCount >= NetClientCount)))
         )
         then
         begin // Íàæàëè <Enter>/<Ïðîáåë> èëè ïðîøëî äîñòàòî÷íî âðåìåíè:
@@ -1708,6 +1730,22 @@ begin
             end;
 
           Exit;
+        end
+        else if g_Game_IsClient and
+        (
+          (
+            e_KeyPressed(IK_RETURN) or e_KeyPressed(IK_KPRETURN) or e_KeyPressed(IK_SPACE) or
+            e_KeyPressed(VK_FIRE) or e_KeyPressed(VK_OPEN) or
+            e_KeyPressed(JOY0_ATTACK) or e_KeyPressed(JOY1_ATTACK) or
+            e_KeyPressed(JOY2_ATTACK) or e_KeyPressed(JOY3_ATTACK)
+          )
+          and (not gJustChatted) and (not gConsoleShow) and (not gChatShow)
+          and (g_ActiveWindow = nil)
+        )
+        then
+        begin
+          // ready / unready
+          InterReady();
         end;
 
         if gState = STATE_INTERTEXT then
@@ -1722,6 +1760,7 @@ begin
           // Çàêîí÷èëñÿ óðîâåíü â Ñâîåé èãðå:
             if gGameSettings.GameType in [GT_CUSTOM, GT_SERVER, GT_CLIENT] then
               begin
+                InterReadyTime := -1;
                 if gLastMap and (gGameSettings.GameMode = GM_COOP) then
                 begin
                   g_Game_ExecuteEvent('onwadend');
@@ -2683,9 +2722,12 @@ begin
               gg := g;
               bb := b;
             end;
-            e_TextureFontPrintEx(x+8, _y, Name, gStdFont, rr, gg, bb, 1);
-            e_TextureFontPrintEx(x+w1+8, _y, IntToStr(Frags), gStdFont, rr, gg, bb, 1);
-            e_TextureFontPrintEx(x+w1+w2+8, _y, IntToStr(Deaths), gStdFont, rr, gg, bb, 1);
+            if (gPlayers[Num] <> nil) and (gPlayers[Num].FReady) then
+              e_TextureFontPrintEx(x+16, _y, Name + ' *', gStdFont, rr, gg, bb, 1)
+            else
+              e_TextureFontPrintEx(x+16, _y, Name, gStdFont, rr, gg, bb, 1);
+            e_TextureFontPrintEx(x+w1+16, _y, IntToStr(Frags), gStdFont, rr, gg, bb, 1);
+            e_TextureFontPrintEx(x+w1+w2+16, _y, IntToStr(Deaths), gStdFont, rr, gg, bb, 1);
             _y := _y+24;
           end;
 
@@ -2710,7 +2752,10 @@ begin
         else
           r := 255;
 
-        e_TextureFontPrintEx(x+8+16+8, _y+4, Name, gStdFont, r, r, r, 1, True);
+        if (gPlayers[Num] <> nil) and (gPlayers[Num].FReady) then
+          e_TextureFontPrintEx(x+8+16+8, _y+4, Name + ' *', gStdFont, r, r, r, 1, True)
+        else
+          e_TextureFontPrintEx(x+8+16+8, _y+4, Name, gStdFont, r, r, r, 1, True);
         e_TextureFontPrintEx(x+w1+8+16+8, _y+4, IntToStr(Frags), gStdFont, r, r, r, 1, True);
         e_TextureFontPrintEx(x+w1+w2+8+16+8, _y+4, IntToStr(Deaths), gStdFont, r, r, r, 1, True);
         _y := _y+24;
@@ -4640,7 +4685,8 @@ begin
 
     ProcessLoading(true);
 
-    if e_KeyPressed(IK_ESCAPE) or e_KeyPressed(IK_SPACE) or e_KeyPressed(VK_ESCAPE) then
+    if e_KeyPressed(IK_SPACE) or e_KeyPressed(IK_ESCAPE) or e_KeyPressed(VK_ESCAPE) or
+       e_KeyPressed(JOY0_JUMP) or e_KeyPressed(JOY1_JUMP) or e_KeyPressed(JOY2_JUMP) or e_KeyPressed(JOY3_JUMP) then
     begin
       State := 0;
       break;
@@ -5802,11 +5848,6 @@ begin
 
       g_Console_Add(Format(cmd + ' is %d', [Byte(g_Debug_Player)]));
     end
-    else if (cmd = 'd_joy') then
-    begin
-      for a := 1 to 8 do
-        g_Console_Add(e_JoystickStateToString(a));
-    end
     else if (cmd = 'd_mem') then
     begin
       PrintHeapStats();
@@ -6367,7 +6408,9 @@ begin
   else if (cmd = 'addbot') or
      (cmd = 'bot_add') then
   begin
-    if Length(P) > 1 then
+    if Length(P) > 2 then
+      g_Bot_Add(TEAM_NONE, StrToIntDef(P[1], 2), StrToIntDef(P[2], 100))
+    else if Length(P) > 1 then
       g_Bot_Add(TEAM_NONE, StrToIntDef(P[1], 2))
     else
       g_Bot_Add(TEAM_NONE, 2);
@@ -6375,10 +6418,14 @@ begin
   else if cmd = 'bot_addlist' then
   begin
     if Length(P) > 1 then
+    begin
       if Length(P) = 2 then
         g_Bot_AddList(TEAM_NONE, P[1], StrToIntDef(P[1], -1))
+      else if Length(P) = 3 then
+        g_Bot_AddList(TEAM_NONE, P[1], StrToIntDef(P[1], -1), StrToIntDef(P[2], 100))
       else
         g_Bot_AddList(IfThen(P[2] = 'red', TEAM_RED, TEAM_BLUE), P[1], StrToIntDef(P[1], -1));
+    end;
   end
   else if cmd = 'bot_removeall' then
     g_Bot_RemoveAll()
@@ -6575,12 +6622,13 @@ begin
           end else
           begin
             // Òàêîé êàðòû íåò, èùåì WAD ôàéë
-            P[1] := addWadExtension(P[1]);
-            g_Console_Add(Format(_lc[I_MSG_NO_MAP_FALLBACK], [s, P[1]]));
-            if FileExists(MapsDir + P[1]) then
+            pw := findDiskWad(MapsDir + P[1]);
+            g_Console_Add(Format(_lc[I_MSG_NO_MAP_FALLBACK], [s, 'WAD ' + P[1]]));
+            if FileExists(pw) then
             begin
               // Ïàðàìåòðà êàðòû íåò, ïîýòîìó ñòàâèì ïåðâóþ èç ôàéëà
               SetLength(P, 3);
+              P[1] := ExtractRelativePath(MapsDir, pw);
               P[2] := g_Game_GetFirstMap(MapsDir + P[1]);
 
               s := P[1] + ':\' + P[2];
@@ -6804,26 +6852,13 @@ begin
   begin
     g_TakeScreenShot()
   end
-  else if cmd = 'togglechat' then
-  begin
-    g_Console_Chat_Switch(False);
-    gSkipFirstChar := not g_Console_Interactive()
-  end
-  else if cmd = 'toggleteamchat' then
-  begin
-    if gGameSettings.GameMode in [GM_TDM, GM_CTF] then
-    begin
-      g_Console_Chat_Switch(True);
-      gSkipFirstChar := not g_Console_Interactive()
-    end
-  end
   else if cmd = 'weapon' then
   begin
     if Length(p) = 2 then
     begin
       a := WP_FIRST + StrToInt(p[1]) - 1;
       if (a >= WP_FIRST) and (a <= WP_LAST) then
-        gSelectWeapon[0] := a
+        gSelectWeapon[0, a] := True
     end
   end
   else if (cmd = 'p1_weapon') or (cmd = 'p2_weapon') then
@@ -6833,7 +6868,7 @@ begin
       a := WP_FIRST + StrToInt(p[1]) - 1;
       b := ord(cmd[2]) - ord('1');
       if (a >= WP_FIRST) and (a <= WP_LAST) then
-        gSelectWeapon[b] := a
+        gSelectWeapon[b, a] := True
     end
   end
 // Êîìàíäû Ñâîåé èãðû: