DEADSOFTWARE

net: tried to spawn a "real" player only after it requested the first full state...
[d2df-sdl.git] / src / game / g_player.pas
index 3549b11b2b5b56a036d448b2939bd7a01787b194..cc6afb07be47661fa320584d0d6ecb2f80f5df1e 100644 (file)
@@ -2,8 +2,7 @@
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, version 3 of the License ONLY.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -97,6 +96,8 @@ const
   SUICIDE_DAMAGE  = 112;
   WEAPON_DELAY    = 5;
 
+  PLAYER_BURN_TIME = 110;
+
   PLAYER1_DEF_COLOR: TRGB = (R:64; G:175; B:48);
   PLAYER2_DEF_COLOR: TRGB = (R:96; G:96; B:96);
 
@@ -267,6 +268,7 @@ type
     FDummy:     Boolean;
     FFireTime:  Integer;
     FHandicap:  Integer;
+    FWaitForFirstSpawn: Boolean; // set to `true` in server, used to spawn a player on first full state request
 
     // debug: viewport offset
     viewPortX, viewPortY, viewPortW, viewPortH: Integer;
@@ -281,6 +283,7 @@ type
     procedure   ReleaseKeys();
     procedure   SetModel(ModelName: String);
     procedure   SetColor(Color: TRGB);
+    function    GetColor(): TRGB;
     procedure   SetWeapon(W: Byte);
     function    IsKeyPressed(K: Byte): Boolean;
     function    GetKeys(): Byte;
@@ -318,7 +321,7 @@ type
     procedure   DrawPickup();
     procedure   DrawRulez();
     procedure   DrawAim();
-    procedure   DrawIndicator();
+    procedure   DrawIndicator(Color: TRGB);
     procedure   DrawBubble();
     procedure   DrawGUI();
     procedure   Update(); virtual;
@@ -336,7 +339,7 @@ type
     procedure   FlamerOff;
     procedure   JetpackOn;
     procedure   JetpackOff;
-    procedure   CatchFire(Attacker: Word);
+    procedure   CatchFire(Attacker: Word; Timeout: Integer = PLAYER_BURN_TIME);
 
     //WARNING! this does nothing for now, but still call it!
     procedure positionChanged (); //WARNING! call this after entity position was changed, or coldet will not work right!
@@ -553,7 +556,8 @@ var
   gFly: Boolean = False;
   gAimLine: Boolean = False;
   gChatBubble: Byte = 0;
-  gPlayerIndicator: Boolean = True;
+  gPlayerIndicator: Integer = 1;
+  gPlayerIndicatorStyle: Integer = 0;
   gNumBots: Word = 0;
   gLMSPID1: Word = 0;
   gLMSPID2: Word = 0;
@@ -2033,6 +2037,11 @@ begin
     if FModel <> nil then FModel.Color := Color;
 end;
 
+function TPlayer.GetColor(): TRGB;
+begin
+  result := FModel.Color;
+end;
+
 procedure TPlayer.SwitchTeam;
 begin
   if g_Game_IsClient then
@@ -2170,6 +2179,8 @@ begin
   FJustTeleported := False;
   FNetTime := 0;
 
+  FWaitForFirstSpawn := false;
+
   resetWeaponQueue();
 end;
 
@@ -2320,23 +2331,72 @@ begin
   inherited;
 end;
 
-procedure TPlayer.DrawIndicator();
+procedure TPlayer.DrawIndicator(Color: TRGB);
 var
   indX, indY: Integer;
   indW, indH: Word;
+  indA: Single;
+  a: TDFPoint;
+  nW, nH: Byte;
   ID: DWORD;
+  c: TRGB;
 begin
   if FAlive then
-    begin
-      if g_Texture_Get('TEXTURE_PLAYER_INDICATOR', ID) then
+    case gPlayerIndicatorStyle of
+      0:
+        begin
+          if g_Texture_Get('TEXTURE_PLAYER_INDICATOR', ID) then
+          begin
+            e_GetTextureSize(ID, @indW, @indH);
+            a.X := indW div 2;
+            a.Y := indH div 2;
+
+            if (FObj.X + FObj.Rect.X) < 0 then
+            begin
+              indA := 90;
+              indX := FObj.X + FObj.Rect.X + FObj.Rect.Width;
+              indY := FObj.Y + FObj.Rect.Y + (FObj.Rect.Height - indW) div 2;
+            end
+
+            else if (FObj.X + FObj.Rect.X + FObj.Rect.Width) > Max(gMapInfo.Width, gPlayerScreenSize.X) then
+            begin
+              indA := 270;
+              indX := FObj.X + FObj.Rect.X - indH;
+              indY := FObj.Y + FObj.Rect.Y + (FObj.Rect.Height - indW) div 2;
+            end
+
+            else if (fObj.Y - indH) < 0 then
+            begin
+              indA := 180;
+              indX := FObj.X + FObj.Rect.X + (FObj.Rect.Width - indW) div 2;
+              indY := FObj.Y + FObj.Rect.Y + FObj.Rect.Height;
+            end
+
+            else
+            begin
+              indA := 0;
+              indX := FObj.X + FObj.Rect.X + (FObj.Rect.Width - indW) div 2;
+              indY := FObj.Y - indH;
+            end;
+
+            indX := EnsureRange(indX, 0, Max(gMapInfo.Width, gPlayerScreenSize.X) - indW);
+            indY := EnsureRange(indY, 0, Max(gMapInfo.Height, gPlayerScreenSize.Y) - indH);
+
+            c := e_Colors;
+            e_Colors := Color;
+            e_DrawAdv(ID, indX, indY, 0, True, False, indA, @a);
+            e_Colors := c;
+          end;
+        end;
+
+      1:
         begin
-          e_GetTextureSize(ID, @indW, @indH);
-          indX := FObj.X + FObj.Rect.X + (FObj.Rect.Width - indW) div 2;
-          indY := FObj.Y;
-          e_Draw(ID, indX, indY - indH, 0, True, False);
+          e_TextureFontGetSize(gStdFont, nW, nH);
+          indX := FObj.X + FObj.Rect.X + (FObj.Rect.Width - Length(FName) * nW) div 2;
+          indY := FObj.Y - nH;
+          e_TextureFontPrintEx(indX, indY, FName, gStdFont, Color.R, Color.G, Color.B, 1.0, True);
         end;
     end;
-  //e_TextureFontPrint(indX, indY, FName, gStdFont); // Shows player name overhead
 end;
 
 procedure TPlayer.DrawBubble();
@@ -3189,13 +3249,17 @@ begin
   FJetSoundOff.PlayAt(FObj.X, FObj.Y);
 end;
 
-procedure TPlayer.CatchFire(Attacker: Word);
+procedure TPlayer.CatchFire(Attacker: Word; Timeout: Integer = PLAYER_BURN_TIME);
 begin
+  if Timeout <= 0 then
+    exit;
   if (FMegaRulez[MR_SUIT] > gTime) or (FMegaRulez[MR_INVUL] > gTime) then
     exit; // Íå çàãîðàåìñÿ êîãäà åñòü çàùèòà
+  if g_Obj_CollidePanel(@FObj, 0, 0, PANEL_WATER or PANEL_ACID1 or PANEL_ACID2) then
+    exit; // Íå ïîäãîðàåì â âîäå íà âñÿêèé ñëó÷àé
   if FFireTime <= 0 then
     g_Sound_PlayExAt('SOUND_IGNITE', FObj.X, FObj.Y);
-  FFireTime := 110;
+  FFireTime := Timeout;
   FFireAttacker := Attacker;
   if g_Game_IsNet and g_Game_IsServer then
     MH_SEND_PlayerStats(FUID);
@@ -7882,4 +7946,6 @@ end;
 
 begin
   conRegVar('cheat_berserk_autoswitch', @gBerserkAutoswitch, 'autoswitch to fist when berserk pack taken', '',  true, true);
+  conRegVar('player_indicator', @gPlayerIndicator, 'Draw indicator only for current player, also for teammates, or not at all', 'Draw indicator only for current player, also for teammates, or not at all');
+  conRegVar('player_indicator_style', @gPlayerIndicatorStyle, 'Visual appearance of indicator', 'Visual appearance of indicator');
 end.