X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_player.pas;h=bfba263a40cf6fb9dbd08781f419d92a7b0b1f9d;hb=9d60dd61d82b1b75e22869d0396a8ee487aa9d5a;hp=558edf291005ae96e782a5a526694dc9b57bb8b5;hpb=dcfda4339af6e1c6fe217cb1e7cbc5d9e09dae6c;p=d2df-sdl.git diff --git a/src/game/g_player.pas b/src/game/g_player.pas index 558edf2..bfba263 100644 --- a/src/game/g_player.pas +++ b/src/game/g_player.pas @@ -212,6 +212,7 @@ type procedure cycleWeapon (dir: Integer); function getNextWeaponIndex (): Byte; // return 255 for "no switch" procedure resetWeaponQueue (); + function hasAmmoForWeapon (weapon: Byte): Boolean; public FDamageBuffer: Integer; @@ -1270,8 +1271,11 @@ begin for i := 0 to High(gPlayers) do if gPlayers[i] <> nil then + begin + gPlayers[i].RealizeCurrentWeapon(); if gPlayers[i] is TPlayer then gPlayers[i].Update() else TBot(gPlayers[i]).Update(); + end; end; procedure g_Player_DrawAll(); @@ -3279,6 +3283,19 @@ begin FNextWeapDelay := 0; end; +function TPlayer.hasAmmoForWeapon (weapon: Byte): Boolean; +begin + result := false; + case weapon of + WEAPON_KASTET, WEAPON_SAW: result := true; + WEAPON_SHOTGUN1, WEAPON_SHOTGUN2: result := (FAmmo[A_SHELLS] > 0); + WEAPON_PISTOL, WEAPON_CHAINGUN, WEAPON_SUPERPULEMET: result := (FAmmo[A_BULLETS] > 0); + WEAPON_ROCKETLAUNCHER: result := (FAmmo[A_ROCKETS] > 0); + WEAPON_PLASMA, WEAPON_BFG: result := (FAmmo[A_CELLS] > 0); + else result := (weapon < length(FWeapon)); + end; +end; + // return 255 for "no switch" function TPlayer.getNextWeaponIndex (): Byte; var @@ -3289,15 +3306,6 @@ begin result := 255; // default result: "no switch" for i := 0 to High(wantThisWeapon) do wantThisWeapon[i] := false; for i := 0 to High(FWeapon) do if (FNextWeap and (1 shl i)) <> 0 then begin wantThisWeapon[i] := true; Inc(wwc); end; - if wantThisWeapon[FCurrWeap] then - begin - // these hacks implements alternating between SG and SSG; sorry - if FCurrWeap = WEAPON_SHOTGUN1 then begin wantThisWeapon[WEAPON_SHOTGUN2] := true; Inc(wwc); end; - if FCurrWeap = WEAPON_SHOTGUN2 then begin wantThisWeapon[WEAPON_SHOTGUN1] := true; Inc(wwc); end; - // these hacks implements alternating between knuckles and chainsaw; sorry - if FCurrWeap = WEAPON_KASTET then begin wantThisWeapon[WEAPON_SAW] := true; Inc(wwc); end; - if FCurrWeap = WEAPON_SAW then begin wantThisWeapon[WEAPON_KASTET] := true; Inc(wwc); end; - end; // exclude currently selected weapon from the set wantThisWeapon[FCurrWeap] := false; // slow down alterations a little @@ -3306,18 +3314,21 @@ begin // more than one weapon requested, assume "alteration" and check alteration delay if FNextWeapDelay > 0 then begin FNextWeap := 0; exit; end; // yeah end; - // no more hacks (yet) // do not reset weapon queue, it will be done in `RealizeCurrentWeapon()` + if wwc < 1 then begin resetWeaponQueue(); exit; end; + //e_WriteLog(Format('wwc=%d', [wwc]), MSG_WARNING); // try weapons in descending order for i := High(FWeapon) downto 0 do begin - if wantThisWeapon[i] and FWeapon[i] then + if wantThisWeapon[i] and FWeapon[i] and ((wwc = 1) or hasAmmoForWeapon(i)) then begin // i found her! result := Byte(i); exit; end; end; + // no suitable weapon found, so reset the queue, to avoid accidental "queuing" of weapon w/o ammo + resetWeaponQueue(); end; procedure TPlayer.RealizeCurrentWeapon(); @@ -3351,13 +3362,11 @@ procedure TPlayer.cycleWeapon (dir: Integer); var i, cwi: Integer; begin - if dir < 0 then dir := 1 else if dir > 0 then dir := 1 else exit; + if dir < 0 then dir := -1 else if dir > 0 then dir := 1 else exit; cwi := FCurrWeap; for i := 0 to High(FWeapon) do begin - cwi := cwi+dir; - if cwi < 0 then cwi += length(FWeapon) - else if cwi > High(FWeapon) then cwi := cwi-length(FWeapon); + cwi := (cwi+length(FWeapon)+dir) mod length(FWeapon); if FWeapon[cwi] then begin QueueWeaponSwitch(Byte(cwi)); @@ -5641,6 +5650,20 @@ begin FJetFuel := JET_MAX; end; + ITEM_MEDKIT_SMALL: if FHealth < PLAYER_HP_SOFT then IncMax(FHealth, 10, PLAYER_HP_SOFT); + ITEM_MEDKIT_LARGE: if FHealth < PLAYER_HP_SOFT then IncMax(FHealth, 25, PLAYER_HP_SOFT); + + ITEM_ARMOR_GREEN: if FArmor < PLAYER_AP_SOFT then FArmor := PLAYER_AP_SOFT; + ITEM_ARMOR_BLUE: if FArmor < PLAYER_AP_LIMIT then FArmor := PLAYER_AP_LIMIT; + + ITEM_SPHERE_BLUE: if FHealth < PLAYER_HP_LIMIT then IncMax(FHealth, 100, PLAYER_HP_LIMIT); + ITEM_SPHERE_WHITE: + if (FHealth < PLAYER_HP_LIMIT) or (FArmor < PLAYER_AP_LIMIT) then + begin + if FHealth < PLAYER_HP_LIMIT then FHealth := PLAYER_HP_LIMIT; + if FArmor < PLAYER_AP_LIMIT then FArmor := PLAYER_AP_LIMIT; + end; + ITEM_WEAPON_SAW: FWeapon[WEAPON_SAW] := True; ITEM_WEAPON_SHOTGUN1: FWeapon[WEAPON_SHOTGUN1] := True; ITEM_WEAPON_SHOTGUN2: FWeapon[WEAPON_SHOTGUN2] := True;