diff --git a/src/game/g_player.pas b/src/game/g_player.pas
index da4c43a84e12561afef525e41c84ce7eb8e04d4a..d6914b1c6fd40425ca90bfcfe7e3434e514ba162 100644 (file)
--- a/src/game/g_player.pas
+++ b/src/game/g_player.pas
*
* 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
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);
FReady: Boolean;
FDummy: Boolean;
FFireTime: Integer;
+ FHandicap: Integer;
// debug: viewport offset
viewPortX, viewPortY, viewPortW, viewPortH: Integer;
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;
procedure DrawPickup();
procedure DrawRulez();
procedure DrawAim();
- procedure DrawIndicator();
+ procedure DrawIndicator(Color: TRGB);
procedure DrawBubble();
procedure DrawGUI();
procedure Update(); virtual;
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!
gFly: Boolean = False;
gAimLine: Boolean = False;
gChatBubble: Byte = 0;
- gPlayerIndicator: Boolean = True;
+ gPlayerIndicator: Byte = 1;
gNumBots: Word = 0;
gLMSPID1: Word = 0;
gLMSPID2: Word = 0;
procedure g_Player_Corpses_SaveState (st: TStream);
procedure g_Player_Corpses_LoadState (st: TStream);
procedure g_Player_ResetReady();
-procedure g_Bot_Add(Team, Difficult: Byte);
-procedure g_Bot_AddList(Team: Byte; lname: ShortString; num: Integer = -1);
+procedure g_Bot_Add(Team, Difficult: Byte; Handicap: Integer = 100);
+procedure g_Bot_AddList(Team: Byte; lname: ShortString; num: Integer = -1; Handicap: Integer = 100);
procedure g_Bot_MixNames();
procedure g_Bot_RemoveAll();
if b = 1 then gPlayers[a].FDirection := TDirection.D_LEFT else gPlayers[a].FDirection := TDirection.D_RIGHT; // b = 2
// Çäîðîâüå
gPlayers[a].FHealth := utils.readLongInt(st);
+ // Ôîðà
+ gPlayers[a].FHandicap := utils.readLongInt(st);
// Æèçíè
gPlayers[a].FLives := utils.readByte(st);
// Áðîíÿ
end;
end;
-procedure g_Bot_Add(Team, Difficult: Byte);
+procedure g_Bot_Add(Team, Difficult: Byte; Handicap: Integer = 100);
var
m: SSArray;
_name, _model: String;
//FDifficult.SafeWeaponPrior[a] := WEAPON_PRIOR3[a];
end;
+ FHandicap := Handicap;
+
g_Console_Add(Format(_lc[I_PLAYER_JOIN], [Name]), True);
if g_Game_IsNet then MH_SEND_PlayerCreate(UID);
end;
end;
-procedure g_Bot_AddList(Team: Byte; lName: ShortString; num: Integer = -1);
+procedure g_Bot_AddList(Team: Byte; lName: ShortString; num: Integer = -1; Handicap: Integer = 100);
var
m: SSArray;
_name, _model: String;
FDifficult.Cover := BotList[num].cover;
FDifficult.CloseJump := BotList[num].close_jump;
+ FHandicap := Handicap;
+
for a := WP_FIRST to WP_LAST do
begin
FDifficult.WeaponPrior[a] := BotList[num].w_prior1[a];
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
FFireTime := 0;
FFirePainTime := 0;
FFireAttacker := 0;
+ FHandicap := 100;
FActualModelName := 'doomer';
inherited;
end;
-procedure TPlayer.DrawIndicator();
+procedure TPlayer.DrawIndicator(Color: TRGB);
var
indX, indY: Integer;
indW, indH: Word;
ID: DWORD;
+ c: TRGB;
begin
if FAlive then
+ begin
+ if g_Texture_Get('TEXTURE_PLAYER_INDICATOR', ID) then
begin
- indX := FObj.X+FObj.Rect.X;
+ e_GetTextureSize(ID, @indW, @indH);
+ indX := FObj.X + FObj.Rect.X + (FObj.Rect.Width - indW) div 2;
indY := FObj.Y;
- if g_Texture_Get('TEXTURE_PLAYER_INDICATOR', ID) then
- begin
- e_GetTextureSize(ID, @indW, @indH);
- e_Draw(ID, indX + indW div 2, indY - indH, 0, True, False);
- end;
+
+ c := e_Colors;
+ e_Colors := Color;
+ e_Draw(ID, indX, indY - indH, 0, True, False);
+ e_Colors := c;
end;
- //e_TextureFontPrint(indX, indY, FName, gStdFont); // Shows player name overhead
+ end;
+ //e_TextureFontPrintEx(indX, indY, FName, gStdFont, 0, 0, 255, 1.0, true); // Shows player name overhead
end;
procedure TPlayer.DrawBubble();
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 := 100;
+ FFireTime := Timeout;
FFireAttacker := Attacker;
if g_Game_IsNet and g_Game_IsServer then
MH_SEND_PlayerStats(FUID);
case ItemType of
ITEM_MEDKIT_SMALL:
- if FHealth < PLAYER_HP_SOFT then
+ if (FHealth < PLAYER_HP_SOFT) or (FFireTime > 0) then
begin
- IncMax(FHealth, 10, PLAYER_HP_SOFT);
+ if FHealth < PLAYER_HP_SOFT then IncMax(FHealth, 10, PLAYER_HP_SOFT);
Result := True;
remove := True;
FFireTime := 0;
end;
ITEM_MEDKIT_LARGE:
- if FHealth < PLAYER_HP_SOFT then
+ if (FHealth < PLAYER_HP_SOFT) or (FFireTime > 0) then
begin
- IncMax(FHealth, 25, PLAYER_HP_SOFT);
+ if FHealth < PLAYER_HP_SOFT then IncMax(FHealth, 25, PLAYER_HP_SOFT);
Result := True;
remove := True;
FFireTime := 0;
end;
ITEM_SPHERE_BLUE:
- if FHealth < PLAYER_HP_LIMIT then
+ if (FHealth < PLAYER_HP_LIMIT) or (FFireTime > 0) then
begin
- IncMax(FHealth, 100, PLAYER_HP_LIMIT);
+ if FHealth < PLAYER_HP_LIMIT then IncMax(FHealth, 100, PLAYER_HP_LIMIT);
Result := True;
remove := True;
FFireTime := 0;
end;
ITEM_SPHERE_WHITE:
- if (FHealth < PLAYER_HP_LIMIT) or (FArmor < PLAYER_AP_LIMIT) then
+ if (FHealth < PLAYER_HP_LIMIT) or (FArmor < PLAYER_AP_LIMIT) or (FFireTime > 0) then
begin
if FHealth < PLAYER_HP_LIMIT then
FHealth := PLAYER_HP_LIMIT;
(FAmmo[A_SHELLS] < FMaxAmmo[A_SHELLS]) or
(FAmmo[A_ROCKETS] < FMaxAmmo[A_ROCKETS]) or
(FAmmo[A_CELLS] < FMaxAmmo[A_CELLS]) or
- (FMaxAmmo[A_FUEL] < AmmoLimits[1, A_FUEL]) then
+ (FAmmo[A_FUEL] < FMaxAmmo[A_FUEL]) then
begin
FMaxAmmo[A_BULLETS] := AmmoLimits[1, A_BULLETS];
FMaxAmmo[A_SHELLS] := AmmoLimits[1, A_SHELLS];
IncMax(FAmmo[A_ROCKETS], 1, FMaxAmmo[A_ROCKETS]);
if FAmmo[A_CELLS] < FMaxAmmo[A_CELLS] then
IncMax(FAmmo[A_CELLS], 40, FMaxAmmo[A_CELLS]);
+ if FAmmo[A_FUEL] < FMaxAmmo[A_FUEL] then
+ IncMax(FAmmo[A_FUEL], 50, FMaxAmmo[A_FUEL]);
FRulez := FRulez + [R_ITEM_BACKPACK];
Result := True;
remove := True;
FFireTime := 0;
end;
- if FHealth < PLAYER_HP_SOFT then
+ if (FHealth < PLAYER_HP_SOFT) or (FFireTime > 0) then
begin
- FHealth := PLAYER_HP_SOFT;
+ if FHealth < PLAYER_HP_SOFT then FHealth := PLAYER_HP_SOFT;
FBerserk := gTime+30000;
Result := True;
remove := True;
end;
ITEM_BOTTLE:
- if FHealth < PLAYER_HP_LIMIT then
+ if (FHealth < PLAYER_HP_LIMIT) or (FFireTime > 0) then
begin
- IncMax(FHealth, 4, PLAYER_HP_LIMIT);
+ if FHealth < PLAYER_HP_LIMIT then IncMax(FHealth, 4, PLAYER_HP_LIMIT);
Result := True;
remove := True;
FFireTime := 0;
// Âîñêðåøåíèå áåç îðóæèÿ:
if not FAlive then
begin
- FHealth := PLAYER_HP_SOFT;
+ FHealth := Round(PLAYER_HP_SOFT * (FHandicap / 100));
FArmor := 0;
FAlive := True;
FAir := AIR_DEF;
if FFirePainTime <= 0 then
begin
if g_Game_IsServer then
- Damage(5, FFireAttacker, 0, 0, HIT_FLAME);
- FFirePainTime := 18;
+ Damage(2, FFireAttacker, 0, 0, HIT_FLAME);
+ FFirePainTime := 12 - FFireTime div 12;
end;
FFirePainTime := FFirePainTime - 1;
FFireTime := FFireTime - 1;
+ if ((FFireTime mod 33) = 0) and (FMegaRulez[MR_INVUL] < gTime) then
+ FModel.PlaySound(MODELSOUND_PAIN, 1, FObj.X, FObj.Y);
if (FFireTime = 0) and g_Game_IsNet and g_Game_IsServer then
MH_SEND_PlayerStats(FUID);
end;
else if FHealth > -50 then Kill(K_HARDKILL, FLastSpawnerUID, FLastHit)
else Kill(K_EXTRAHARDKILL, FLastSpawnerUID, FLastHit);
- if FAlive then
+ if FAlive and ((FLastHit <> HIT_FLAME) or (FFireTime <= 0)) then
begin
if FDamageBuffer <= 20 then FModel.PlaySound(MODELSOUND_PAIN, 1, FObj.X, FObj.Y)
else if FDamageBuffer <= 55 then FModel.PlaySound(MODELSOUND_PAIN, 2, FObj.X, FObj.Y)
utils.writeInt(st, Byte(b));
// Çäîðîâüå
utils.writeInt(st, LongInt(FHealth));
+ // Êîýôôèöèåíò èíâàëèäíîñòè
+ utils.writeInt(st, LongInt(FHandicap));
// Æèçíè
utils.writeInt(st, Byte(FLives));
// Áðîíÿ
if b = 1 then FDirection := TDirection.D_LEFT else FDirection := TDirection.D_RIGHT; // b = 2
// Çäîðîâüå
FHealth := utils.readLongInt(st);
+ // Êîýôôèöèåíò èíâàëèäíîñòè
+ FHandicap := utils.readLongInt(st);
// Æèçíè
FLives := utils.readByte(st);
// Áðîíÿ