DEADSOFTWARE

Game: Revamp prev and next weapon commands
[d2df-sdl.git] / src / game / g_player.pas
index 85b8e1537ad9024686d09be58f5ad61914968249..c1454c81d7b5a3454b011f716fc2460e87c8d314 100644 (file)
@@ -31,11 +31,14 @@ const
   KEY_UP         = 3;
   KEY_DOWN       = 4;
   KEY_FIRE       = 5;
-  KEY_NEXTWEAPON = 6;
-  KEY_PREVWEAPON = 7;
-  KEY_OPEN       = 8;
-  KEY_JUMP       = 9;
-  KEY_CHAT       = 10;
+  KEY_OPEN       = 6;
+  KEY_JUMP       = 7;
+  KEY_CHAT       = 8;
+
+  WP_PREV        = 0;
+  WP_NEXT        = 1;
+  WP_FACT        = WP_PREV;
+  WP_LACT        = WP_NEXT;
 
   R_ITEM_BACKPACK   = 0;
   R_KEY_RED         = 1;
@@ -114,6 +117,7 @@ type
     Kills: Word;
     Color: TRGB;
     Spectator: Boolean;
+    UID: Word;
   end;
 
   TPlayerStatArray = Array of TPlayerStat;
@@ -338,6 +342,7 @@ type
     procedure   NetFire(Wpn: Byte; X, Y, AX, AY: Integer; WID: Integer = -1);
     procedure   DoLerp(Level: Integer = 2);
     procedure   SetLerp(XTo, YTo: Integer);
+    procedure   ProcessWeaponAction(Action: Byte);
     procedure   QueueWeaponSwitch(Weapon: Byte);
     procedure   RealizeCurrentWeapon();
     procedure   FlamerOn;
@@ -533,7 +538,7 @@ type
   public
     constructor Create(X, Y: Integer; ModelName: String; aMess: Boolean);
     destructor  Destroy(); override;
-    procedure   Damage(Value: Word; vx, vy: Integer);
+    procedure   Damage(Value: Word; SpawnerUID: Word; vx, vy: Integer);
     procedure   Update();
     procedure   Draw();
     procedure   SaveState (st: TStream);
@@ -1521,6 +1526,7 @@ begin
         Color := gPlayers[a].FModel.Color;
         Lives := gPlayers[a].FLives;
         Spectator := gPlayers[a].FSpectator;
+        UID := gPlayers[a].FUID;
       end;
     end;
 end;
@@ -2454,8 +2460,11 @@ var
   Rb, Gb, Bb,
   Rw, Gw, Bw: SmallInt;
   Dot: Byte;
+  CObj: TObj;
 begin
-  FObj.lerp(gLerpFactor, fX, fY);
+  CObj := getCameraObj();
+  CObj.lerp(gLerpFactor, fX, fY);
+  // NB: _F_Obj.Rect is used to keep the bubble higher; this is not a mistake
   bubX := fX+FObj.Rect.X + IfThen(FDirection = TDirection.D_LEFT, -4, 18);
   bubY := fY+FObj.Rect.Y - 18;
   Rb := 64;
@@ -3767,6 +3776,15 @@ begin
               FModel.Blood.R, FModel.Blood.G, FModel.Blood.B, FModel.Blood.Kind);
 end;
 
+procedure TPlayer.ProcessWeaponAction(Action: Byte);
+begin
+  if g_Game_IsClient then Exit;
+  case Action of
+    WP_PREV: PrevWeapon();
+    WP_NEXT: NextWeapon();
+  end;
+end;
+
 procedure TPlayer.QueueWeaponSwitch(Weapon: Byte);
 begin
   if g_Game_IsClient then Exit;
@@ -4469,143 +4487,58 @@ begin
   // Îäèíî÷íàÿ èãðà/êîîïåðàòèâ
   if gGameSettings.GameMode in [GM_COOP, GM_SINGLE] then
   begin
-    if (Self = gPlayer1) or (Self = gPlayer2) then
+    if Self = gPlayer1 then
     begin
-      // Òî÷êà ïîÿâëåíèÿ ñâîåãî èãðîêà
-      if Self = gPlayer1 then
-        c := RESPAWNPOINT_PLAYER1
-      else
-        c := RESPAWNPOINT_PLAYER2;
-      if g_Map_GetPointCount(c) > 0 then
-      begin
-        Result := c;
-        Exit;
-      end;
-
-      // Òî÷êà ïîÿâëåíèÿ äðóãîãî èãðîêà
-      if Self = gPlayer1 then
-        c := RESPAWNPOINT_PLAYER2
-      else
-        c := RESPAWNPOINT_PLAYER1;
-      if g_Map_GetPointCount(c) > 0 then
-      begin
-        Result := c;
-        Exit;
-      end;
-    end else
+      // player 1 should try to spawn on the player 1 point
+      if g_Map_GetPointCount(RESPAWNPOINT_PLAYER1) > 0 then
+        Exit(RESPAWNPOINT_PLAYER1)
+      else if g_Map_GetPointCount(RESPAWNPOINT_PLAYER2) > 0 then
+        Exit(RESPAWNPOINT_PLAYER2);
+    end
+    else if Self = gPlayer2 then
     begin
-      // Òî÷êà ïîÿâëåíèÿ ëþáîãî èãðîêà (áîòà)
-      if Random(2) = 0 then
-        c := RESPAWNPOINT_PLAYER1
-      else
-        c := RESPAWNPOINT_PLAYER2;
-      if g_Map_GetPointCount(c) > 0 then
-      begin
-        Result := c;
-        Exit;
-      end;
-    end;
-
-    // Òî÷êà ëþáîé èç êîìàíä
-    if Random(2) = 0 then
-      c := RESPAWNPOINT_RED
+      // player 2 should try to spawn on the player 2 point
+      if g_Map_GetPointCount(RESPAWNPOINT_PLAYER2) > 0 then
+        Exit(RESPAWNPOINT_PLAYER2)
+      else if g_Map_GetPointCount(RESPAWNPOINT_PLAYER1) > 0 then
+        Exit(RESPAWNPOINT_PLAYER1);
+    end
     else
-      c := RESPAWNPOINT_BLUE;
-    if g_Map_GetPointCount(c) > 0 then
     begin
-      Result := c;
-      Exit;
-    end;
-
-    // Òî÷êà DM
-    c := RESPAWNPOINT_DM;
-    if g_Map_GetPointCount(c) > 0 then
-    begin
-      Result := c;
-      Exit;
+      // other players randomly pick either the first or the second point
+      c := IfThen((Random(2) = 0), RESPAWNPOINT_PLAYER1, RESPAWNPOINT_PLAYER2);
+      if g_Map_GetPointCount(c) > 0 then
+        Exit(c);
+        // try the other one
+      c := IfThen((c = RESPAWNPOINT_PLAYER1), RESPAWNPOINT_PLAYER2, RESPAWNPOINT_PLAYER1);
+      if g_Map_GetPointCount(c) > 0 then
+        Exit(c);
     end;
   end;
 
   // Ìÿñîïîâàë
   if gGameSettings.GameMode = GM_DM then
   begin
-    // Òî÷êà DM
-    c := RESPAWNPOINT_DM;
-    if g_Map_GetPointCount(c) > 0 then
-    begin
-      Result := c;
-      Exit;
-    end;
-
-    // Òî÷êà ïîÿâëåíèÿ ëþáîãî èãðîêà
-    if Random(2) = 0 then
-      c := RESPAWNPOINT_PLAYER1
-    else
-      c := RESPAWNPOINT_PLAYER2;
-    if g_Map_GetPointCount(c) > 0 then
-    begin
-      Result := c;
-      Exit;
-    end;
-
-    // Òî÷êà ëþáîé èç êîìàíä
-    if Random(2) = 0 then
-      c := RESPAWNPOINT_RED
-    else
-      c := RESPAWNPOINT_BLUE;
-    if g_Map_GetPointCount(c) > 0 then
-    begin
-      Result := c;
-      Exit;
-    end;
+    // try DM points first
+    if g_Map_GetPointCount(RESPAWNPOINT_DM) > 0 then
+      Exit(RESPAWNPOINT_DM);
   end;
 
   // Êîìàíäíûå
   if gGameSettings.GameMode in [GM_TDM, GM_CTF] then
   begin
-    // Òî÷êà ñâîåé êîìàíäû
-    c := RESPAWNPOINT_DM;
-    if FTeam = TEAM_RED then
-      c := RESPAWNPOINT_RED;
-    if FTeam = TEAM_BLUE then
-      c := RESPAWNPOINT_BLUE;
-    if g_Map_GetPointCount(c) > 0 then
-    begin
-      Result := c;
-      Exit;
-    end;
-
-    // Òî÷êà DM
-    c := RESPAWNPOINT_DM;
-    if g_Map_GetPointCount(c) > 0 then
-    begin
-      Result := c;
-      Exit;
-    end;
-
-    // Òî÷êà ïîÿâëåíèÿ ëþáîãî èãðîêà
-    if Random(2) = 0 then
-      c := RESPAWNPOINT_PLAYER1
-    else
-      c := RESPAWNPOINT_PLAYER2;
-    if g_Map_GetPointCount(c) > 0 then
-    begin
-      Result := c;
-      Exit;
-    end;
-
-    // Òî÷êà äðóãîé êîìàíäû
+    // try team points first
     c := RESPAWNPOINT_DM;
     if FTeam = TEAM_RED then
+      c := RESPAWNPOINT_RED
+    else if FTeam = TEAM_BLUE then
       c := RESPAWNPOINT_BLUE;
-    if FTeam = TEAM_BLUE then
-      c := RESPAWNPOINT_RED;
     if g_Map_GetPointCount(c) > 0 then
-    begin
-      Result := c;
-      Exit;
-    end;
+      Exit(c);
   end;
+
+  // still haven't found a spawnpoint, try random shit
+  Result := g_Map_GetRandomPointType();
 end;
 
 procedure TPlayer.Respawn(Silent: Boolean; Force: Boolean = False);
@@ -5142,10 +5075,6 @@ begin
     FIncCam := FIncCam*i;
   end;
 
-  // no need to do that each second frame, weapon queue will take care of it
-  if FAlive and FKeys[KEY_NEXTWEAPON].Pressed and AnyServer then NextWeapon();
-  if FAlive and FKeys[KEY_PREVWEAPON].Pressed and AnyServer then PrevWeapon();
-
   if gTime mod (GAME_TICK*2) <> 0 then
   begin
     if (FObj.Vel.X = 0) and FAlive then
@@ -5172,8 +5101,6 @@ begin
     // Let alive player do some actions
     if FKeys[KEY_LEFT].Pressed then Run(TDirection.D_LEFT);
     if FKeys[KEY_RIGHT].Pressed then Run(TDirection.D_RIGHT);
-    //if FKeys[KEY_NEXTWEAPON].Pressed and AnyServer then NextWeapon();
-    //if FKeys[KEY_PREVWEAPON].Pressed and AnyServer then PrevWeapon();
     if FKeys[KEY_FIRE].Pressed and AnyServer then Fire()
     else
     begin
@@ -5776,10 +5703,15 @@ var
 begin
   FXTo := XTo;
   FYTo := YTo;
-  if NetInterpLevel < 1 then
+  if FJustTeleported or (NetInterpLevel < 1) then
   begin
     FObj.X := XTo;
     FObj.Y := YTo;
+    if FJustTeleported then
+    begin
+      FObj.oldX := FObj.X;
+      FObj.oldY := FObj.Y;
+    end;
   end
   else
   begin
@@ -6614,7 +6546,7 @@ begin
 end;
 
 
-procedure TCorpse.Damage(Value: Word; vx, vy: Integer);
+procedure TCorpse.Damage(Value: Word; SpawnerUID: Word; vx, vy: Integer);
 var
   pm: TPlayerModel;
   Blood: TModelBlood;
@@ -6645,7 +6577,7 @@ begin
         if (gBodyKillEvent <> -1)
         and gDelayedEvents[gBodyKillEvent].Pending then
           gDelayedEvents[gBodyKillEvent].Pending := False;
-        gBodyKillEvent := g_Game_DelayEvent(DE_BODYKILL, 1050, 0);
+        gBodyKillEvent := g_Game_DelayEvent(DE_BODYKILL, 1050, SpawnerUID);
       end;
     end
   else