DEADSOFTWARE

Game: Use proper syntax of sets for game options instead of raw bitwise operations
[d2df-sdl.git] / src / game / g_player.pas
index 8f4331079506d89ee91e6c0b00d13701ad8c5153..a97b4ff5a50f911853570883bf99b190b9851573 100644 (file)
@@ -133,7 +133,7 @@ type
     Ammo:       Array [A_BULLETS..A_HIGH] of Word;
     MaxAmmo:    Array [A_BULLETS..A_HIGH] of Word;
     Weapon:     Array [WP_FIRST..WP_LAST] of Boolean;
-    Rulez:      Set of R_ITEM_BACKPACK..R_BERSERK;
+    Inventory:  Set of R_ITEM_BACKPACK..R_BERSERK;
     Used:       Boolean;
   end;
 
@@ -237,9 +237,10 @@ type
     procedure Jump();
     procedure Use();
 
-    function getNextWeaponIndex (): Byte; // return 255 for "no switch"
+    function getNextWeaponIndex (): Byte;  // returns 255 for "no switch"
     procedure resetWeaponQueue ();
     function hasAmmoForWeapon (weapon: Byte): Boolean;
+    function hasAmmoForShooting (weapon: Byte): Boolean;
     function shouldSwitch (weapon: Byte; hadWeapon: Boolean) : Boolean;
 
     procedure doDamage (v: Integer);
@@ -252,16 +253,16 @@ type
     FAmmo:      Array [A_BULLETS..A_HIGH] of Word;
     FMaxAmmo:   Array [A_BULLETS..A_HIGH] of Word;
     FWeapon:    Array [WP_FIRST..WP_LAST] of Boolean;
-    FRulez:     Set of R_ITEM_BACKPACK..R_BERSERK;
+    FInventory: Set of R_ITEM_BACKPACK..R_BERSERK;
     FBerserk:   Integer;
-    FMegaRulez: Array [MR_SUIT..MR_MAX] of DWORD;
+    FPowerups:  Array [MR_SUIT..MR_MAX] of DWORD;
     FReloading: Array [WP_FIRST..WP_LAST] of Word;
     FTime:      Array [T_RESPAWN..T_FLAGCAP] of DWORD;
     FKeys:      Array [KEY_LEFT..KEY_CHAT] of TKeyState;
     FWeapSwitchMode: Byte;
     FWeapPreferences: Array [WP_FIRST .. WP_LAST+1] of Byte;
     FSwitchToEmpty: Byte;
-    FSkipFist: Byte;
+    FSkipIronFist: Byte;
     FColor:     TRGB;
     FPreferredTeam: Byte;
     FSpectator: Boolean;
@@ -322,7 +323,7 @@ type
     procedure   SetFlag(Flag: Byte);
     function    DropFlag(Silent: Boolean = True; DoThrow: Boolean = False): Boolean;
     function    TryDropFlag(): Boolean;
-    procedure   AllRulez(Health: Boolean);
+    procedure   TankRamboCheats(Health: Boolean);
     procedure   RestoreHealthArmor();
     procedure   FragCombo();
     procedure   GiveItem(ItemType: Byte);
@@ -338,15 +339,15 @@ type
     procedure   Draw(); virtual;
     procedure   DrawPain();
     procedure   DrawPickup();
-    procedure   DrawRulez();
+    procedure   DrawOverlay();
     procedure   DrawAim();
     procedure   DrawIndicator(Color: TRGB);
     procedure   DrawBubble();
     procedure   DrawGUI();
     procedure   PreUpdate();
     procedure   Update(); virtual;
-    procedure   RememberState();
-    procedure   RecallState();
+    procedure   PreserveState();
+    procedure   RestoreState();
     procedure   SaveState (st: TStream); virtual;
     procedure   LoadState (st: TStream); virtual;
     procedure   PauseSounds(Enable: Boolean);
@@ -387,7 +388,7 @@ type
     property    CurrWeap: Byte read FCurrWeap write FCurrWeap;
     property    WeapSwitchMode: Byte read FWeapSwitchMode write FWeapSwitchMode;
     property    SwitchToEmpty: Byte read FSwitchToEmpty write FSwitchToEmpty;
-    property    SkipFist: Byte read FSkipFist write FSkipFist;
+    property    SkipIronFist: Byte read FSkipIronFist write FSkipIronFist;
     property    MonsterKills: Integer read FMonsterKills write FMonsterKills;
     property    Secrets: Integer read FSecrets;
     property    GodMode: Boolean read FGodMode write FGodMode;
@@ -572,7 +573,7 @@ type
 
   TTeamStat = Array [TEAM_RED..TEAM_BLUE] of
     record
-      Goals: SmallInt;
+      Score: SmallInt;
     end;
 
 var
@@ -599,6 +600,10 @@ procedure g_Gibs_SetMax(Count: Word);
 function  g_Gibs_GetMax(): Word;
 procedure g_Corpses_SetMax(Count: Word);
 function  g_Corpses_GetMax(): Word;
+procedure g_Force_Model_Set(Mode: Word);
+function g_Force_Model_Get(): Word;
+procedure g_Forced_Model_SetName(Model: String);
+function  g_Forced_Model_GetName(): String;
 procedure g_Shells_SetMax(Count: Word);
 function  g_Shells_GetMax(): Word;
 
@@ -618,7 +623,7 @@ procedure g_Player_ResetAll(Force, Silent: Boolean);
 function  g_Player_Get(UID: Word): TPlayer;
 function  g_Player_GetCount(): Byte;
 function  g_Player_GetStats(): TPlayerStatArray;
-function  g_Player_ValidName(Name: String): Boolean;
+function  g_Player_ExistingName(Name: String): Boolean;
 function  g_Player_CreateCorpse(Player: TPlayer): Integer;
 procedure g_Player_CreateGibs(fX, fY: Integer; ModelName: String; fColor: TRGB);
 procedure g_Player_CreateShell(fX, fY, dX, dY: Integer; T: Byte);
@@ -633,6 +638,7 @@ 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();
+function g_Bot_GetCount(): Integer;
 
 implementation
 
@@ -700,20 +706,20 @@ const
                                 FlyPrecision: 255; Cover: 255; CloseJump: 255;
                                 WeaponPrior:(0,0,0,0,0,0,0,0,0,0,0); CloseWeaponPrior:(0,0,0,0,0,0,0,0,0,0,0));
   WEAPON_PRIOR1: Array [WP_FIRST..WP_LAST] of Byte =
-                                (WEAPON_FLAMETHROWER, WEAPON_SUPERPULEMET,
+                                (WEAPON_FLAMETHROWER, WEAPON_SUPERCHAINGUN,
                                  WEAPON_SHOTGUN2, WEAPON_SHOTGUN1,
                                  WEAPON_CHAINGUN, WEAPON_PLASMA, WEAPON_ROCKETLAUNCHER,
-                                 WEAPON_BFG, WEAPON_PISTOL, WEAPON_SAW, WEAPON_KASTET);
+                                 WEAPON_BFG, WEAPON_PISTOL, WEAPON_SAW, WEAPON_IRONFIST);
   WEAPON_PRIOR2: Array [WP_FIRST..WP_LAST] of Byte =
-                                (WEAPON_FLAMETHROWER, WEAPON_SUPERPULEMET,
+                                (WEAPON_FLAMETHROWER, WEAPON_SUPERCHAINGUN,
                                  WEAPON_BFG, WEAPON_ROCKETLAUNCHER,
                                  WEAPON_SHOTGUN2, WEAPON_PLASMA, WEAPON_SHOTGUN1,
-                                 WEAPON_CHAINGUN, WEAPON_PISTOL, WEAPON_SAW, WEAPON_KASTET);
+                                 WEAPON_CHAINGUN, WEAPON_PISTOL, WEAPON_SAW, WEAPON_IRONFIST);
   //WEAPON_PRIOR3: Array [WP_FIRST..WP_LAST] of Byte =
-  //                              (WEAPON_FLAMETHROWER, WEAPON_SUPERPULEMET,
+  //                              (WEAPON_FLAMETHROWER, WEAPON_SUPERCHAINGUN,
   //                               WEAPON_BFG, WEAPON_PLASMA, WEAPON_SHOTGUN2,
   //                               WEAPON_CHAINGUN, WEAPON_SHOTGUN1, WEAPON_SAW,
-  //                               WEAPON_ROCKETLAUNCHER, WEAPON_PISTOL, WEAPON_KASTET);
+  //                               WEAPON_ROCKETLAUNCHER, WEAPON_PISTOL, WEAPON_IRONFIST);
   WEAPON_RELOAD: Array [WP_FIRST..WP_LAST] of Byte =
                                 (5, 2, 6, 18, 36, 2, 12, 2, 14, 2, 2);
 
@@ -727,6 +733,8 @@ var
   MaxGibs: Word = 150;
   MaxCorpses: Word = 20;
   MaxShells: Word = 300;
+  ForceModel: Word = 0;
+  ForcedModelName: String = STD_PLAYER_MODEL;
   CurrentGib: Integer = 0;
   CurrentShell: Integer = 0;
   BotNames: Array of String;
@@ -794,6 +802,26 @@ begin
   Result := MaxCorpses;
 end;
 
+procedure g_Force_Model_Set(Mode: Word);
+begin
+  ForceModel := Mode;
+end;
+
+function g_Force_Model_Get(): Word;
+begin
+  Result := ForceModel;
+end;
+
+procedure g_Forced_Model_SetName(Model: String);
+begin
+  ForcedModelName := Model;
+end;
+
+function g_Forced_Model_GetName(): String;
+begin
+  Result := ForcedModelName;
+end;
+
 function g_Player_Create(ModelName: String; Color: TRGB; Team: Byte; Bot: Boolean): Word;
 var
   a: Integer;
@@ -829,6 +857,8 @@ begin
 
   gPlayers[a].FActualModelName := ModelName;
   gPlayers[a].SetModel(ModelName);
+  if Bot and (g_Force_Model_Get() <> 0) then
+    gPlayers[a].SetModel(g_Forced_Model_GetName());
 
 // Íåò ìîäåëè - ñîçäàíèå íå âîçìîæíî:
   if gPlayers[a].FModel = nil then
@@ -897,7 +927,11 @@ begin
 
   // create entity and load state
   if Bot then
-    gPlayers[a] := TBot.Create()
+  begin
+    gPlayers[a] := TBot.Create();
+    if (g_Force_Model_Get() <> 0) then
+      gPlayers[a].SetModel(g_Forced_Model_GetName());
+  end
   else
     gPlayers[a] := TPlayer.Create();
   gPlayers[a].FPhysics := True; // ???
@@ -943,6 +977,9 @@ var
 begin
   if not g_Game_IsServer then Exit;
 
+// Íå äîáàâëÿåì áîòîâ åñëè ëèìèò óæå äîñòèãíóò
+  if (g_Bot_GetCount() >= gMaxBots) then Exit;
+
 // Ñïèñîê íàçâàíèé ìîäåëåé:
   m := g_PlayerModel_GetNames();
   if m = nil then
@@ -987,7 +1024,7 @@ begin
   _name := '';
   if BotNames <> nil then
     for a := 0 to High(BotNames) do
-      if g_Player_ValidName(BotNames[a]) then
+      if g_Player_ExistingName(BotNames[a]) then
       begin
         _name := BotNames[a];
         Break;
@@ -1040,6 +1077,9 @@ var
 begin
   if not g_Game_IsServer then Exit;
 
+// Íå äîáàâëÿåì áîòîâ åñëè ëèìèò óæå äîñòèãíóò
+  if (g_Bot_GetCount() >= gMaxBots) then Exit;
+
 // Ñïèñîê íàçâàíèé ìîäåëåé:
   m := g_PlayerModel_GetNames();
   if m = nil then
@@ -1056,26 +1096,33 @@ begin
         Team := BotList[num].team; // CTF / TDM
 
 // Âûáèðàåì íàñòðîéêè áîòà èç ñïèñêà ïî íîìåðó èëè èìåíè:
-  lName := AnsiLowerCase(lName);
-  if (num < 0) or (num > Length(BotList)-1) then
-    num := -1;
-  if (num = -1) and (lName <> '') and (BotList <> nil) then
-    for a := 0 to High(BotList) do
-      if AnsiLowerCase(BotList[a].name) = lName then
-      begin
-        num := a;
-        Break;
-      end;
-  if num = -1 then
-    Exit;
+  if lName = '' then
+    num := Random(Length(BotList))
+  else
+  begin
+    if (num < 0) or (num > Length(BotList)-1) then
+      num := -1;
+    if (num = -1) and (BotList <> nil) then
+      lName := AnsiLowerCase(lName);
+      for a := 0 to High(BotList) do
+        if AnsiLowerCase(BotList[a].name) = lName then
+        begin
+          num := a;
+          Break;
+        end;
+    if num = -1 then
+      Exit;
+  end;
 
 // Èìÿ áîòà:
   _name := BotList[num].name;
-// Çàíÿòî - âûáèðàåì ñëó÷àéíîå:
-  if not g_Player_ValidName(_name) then
-  repeat
-    _name := Format('DFBOT%.2d', [Random(100)]);
-  until g_Player_ValidName(_name);
+  if (_name = '') and (BotNames <> nil) then
+    for a := 0 to High(BotNames) do
+      if g_Player_ExistingName(BotNames[a]) then
+      begin
+        _name := BotNames[a];
+        Break;
+      end;
 
 // Ìîäåëü:
   _model := BotList[num].model;
@@ -1086,7 +1133,10 @@ begin
 // Ñîçäàåì áîòà:
   with g_Player_Get(g_Player_Create(_model, BotList[num].color, Team, True)) as TBot do
   begin
-    Name := _name;
+  // Åñëè èìåíè íåò, äåëàåì åãî èç UID áîòà
+    if _name = ''
+      then Name := Format('DFBOT%.5d', [UID])
+      else Name := _name;
 
     FDifficult.DiagFire := BotList[num].diag_fire;
     FDifficult.InvisFire := BotList[num].invis_fire;
@@ -1177,90 +1227,96 @@ var
   path: AnsiString;
 begin
   BotNames := nil;
+  BotList := nil;
 
   path := BOTNAMES_FILENAME;
-  if e_FindResource(DataDirs, path) = false then
-    Exit;
-
-// ×èòàåì âîçìîæíûå èìåíà áîòîâ èç ôàéëà:
-  AssignFile(F, path);
-  Reset(F);
-
-  while not EOF(F) do
+  if e_FindResource(DataDirs, path) then
   begin
-    ReadLn(F, s);
+    // ×èòàåì âîçìîæíûå èìåíà áîòîâ èç ôàéëà:
+    AssignFile(F, path);
+    Reset(F);
 
-    s := Trim(s);
-    if s = '' then
-      Continue;
+    while not EOF(F) do
+    begin
+      ReadLn(F, s);
 
-    SetLength(BotNames, Length(BotNames)+1);
-    BotNames[High(BotNames)] := s;
-  end;
+      s := Trim(s);
+      if s = '' then
+        Continue;
 
-  CloseFile(F);
+      SetLength(BotNames, Length(BotNames)+1);
+      BotNames[High(BotNames)] := s;
+    end;
 
-// Ïåðåìåøèâàåì èõ:
-  g_Bot_MixNames();
+    CloseFile(F);
 
-// ×èòàåì ôàéë ñ ïàðàìåòðàìè áîòîâ:
-  config := TConfig.CreateFile(path);
-  BotList := nil;
-  a := 0;
+    // Ïåðåìåøèâàåì èõ:
+    g_Bot_MixNames();
+  end;
 
-  while config.SectionExists(IntToStr(a)) do
+  path := BOTLIST_FILENAME;
+  if e_FindResource(DataDirs, path) then
   begin
-    SetLength(BotList, Length(BotList)+1);
+    // ×èòàåì ôàéë ñ ïàðàìåòðàìè áîòîâ:
+    config := TConfig.CreateFile(path);
+    a := 0;
 
-    with BotList[High(BotList)] do
+    while config.SectionExists(IntToStr(a)) do
     begin
-    // Èìÿ áîòà:
-      name := config.ReadStr(IntToStr(a), 'name', '');
-    // Ìîäåëü:
-      model := config.ReadStr(IntToStr(a), 'model', '');
-    // Êîìàíäà:
-      if config.ReadStr(IntToStr(a), 'team', 'red') = 'red' then
-        team := TEAM_RED
-      else
-        team := TEAM_BLUE;
-    // Öâåò ìîäåëè:
-      sa := parse(config.ReadStr(IntToStr(a), 'color', ''));
-      color.R := StrToIntDef(sa[0], 0);
-      color.G := StrToIntDef(sa[1], 0);
-      color.B := StrToIntDef(sa[2], 0);
-    // Âåðîÿòíîñòü ñòðåëüáû ïîä óãëîì:
-      diag_fire := config.ReadInt(IntToStr(a), 'diag_fire', 0);
-    // Âåðîÿòíîñòü îòâåòíîãî îãíÿ ïî íåâèäèìîìó ñîïåðíèêó:
-      invis_fire := config.ReadInt(IntToStr(a), 'invis_fire', 0);
-    // Òî÷íîñòü ñòðåëüáû ïîä óãëîì:
-      diag_precision := config.ReadInt(IntToStr(a), 'diag_precision', 0);
-    // Òî÷íîñòü ñòðåëüáû â ïîëåòå:
-      fly_precision := config.ReadInt(IntToStr(a), 'fly_precision', 0);
-    // Òî÷íîñòü óêëîíåíèÿ îò ñíàðÿäîâ:
-      cover := config.ReadInt(IntToStr(a), 'cover', 0);
-    // Âåðîÿòíîñòü ïðûæêà ïðè ïðèáëèæåíèè ñîïåðíèêà:
-      close_jump := config.ReadInt(IntToStr(a), 'close_jump', 0);
-    // Ïðèîðèòåòû îðóæèÿ äëÿ äàëüíåãî áîÿ:
-      sa := parse(config.ReadStr(IntToStr(a), 'w_prior1', ''));
-      if Length(sa) = 10 then
-        for b := 0 to 9 do
-          w_prior1[b] := EnsureRange(StrToInt(sa[b]), 0, 9);
-    // Ïðèîðèòåòû îðóæèÿ äëÿ áëèæíåãî áîÿ:
-      sa := parse(config.ReadStr(IntToStr(a), 'w_prior2', ''));
-      if Length(sa) = 10 then
-        for b := 0 to 9 do
-          w_prior2[b] := EnsureRange(StrToInt(sa[b]), 0, 9);
-
-      {sa := parse(config.ReadStr(IntToStr(a), 'w_prior3', ''));
-      if Length(sa) = 10 then
-        for b := 0 to 9 do
-          w_prior3[b] := EnsureRange(StrToInt(sa[b]), 0, 9);}
+      SetLength(BotList, Length(BotList)+1);
+
+      with BotList[High(BotList)] do
+      begin
+        name := config.ReadStr(IntToStr(a), 'name', '');  // Èìÿ áîòà
+        model := config.ReadStr(IntToStr(a), 'model', '');  // Ìîäåëü
+
+        // Êîìàíäà
+        s := config.ReadStr(IntToStr(a), 'team', '');
+        if s = 'red' then
+          team := TEAM_RED
+        else if s = 'blue' then
+          team := TEAM_BLUE
+        else
+          team := TEAM_NONE;
+
+        // Öâåò ìîäåëè
+        sa := parse(config.ReadStr(IntToStr(a), 'color', ''));
+        SetLength(sa, 3);
+        color.R := StrToIntDef(sa[0], 0);
+        color.G := StrToIntDef(sa[1], 0);
+        color.B := StrToIntDef(sa[2], 0);
+
+        diag_fire := config.ReadInt(IntToStr(a), 'diag_fire', 0);  // Âåðîÿòíîñòü ñòðåëüáû ïîä óãëîì
+        invis_fire := config.ReadInt(IntToStr(a), 'invis_fire', 0);  // Âåðîÿòíîñòü îòâåòíîãî îãíÿ ïî íåâèäèìîìó ñîïåðíèêó
+        diag_precision := config.ReadInt(IntToStr(a), 'diag_precision', 0);  // Òî÷íîñòü ñòðåëüáû ïîä óãëîì
+        fly_precision := config.ReadInt(IntToStr(a), 'fly_precision', 0);  // Òî÷íîñòü ñòðåëüáû â ïîëåòå
+        cover := config.ReadInt(IntToStr(a), 'cover', 0);  // Òî÷íîñòü óêëîíåíèÿ îò ñíàðÿäîâ
+        close_jump := config.ReadInt(IntToStr(a), 'close_jump', 0);  // Âåðîÿòíîñòü ïðûæêà ïðè ïðèáëèæåíèè ñîïåðíèêà
+
+        // Ïðèîðèòåòû îðóæèÿ äëÿ äàëüíåãî áîÿ
+        sa := parse(config.ReadStr(IntToStr(a), 'w_prior1', ''));
+        if Length(sa) = 10 then
+          for b := 0 to 9 do
+            w_prior1[b] := EnsureRange(StrToInt(sa[b]), 0, 9);
+
+        // Ïðèîðèòåòû îðóæèÿ äëÿ áëèæíåãî áîÿ
+        sa := parse(config.ReadStr(IntToStr(a), 'w_prior2', ''));
+        if Length(sa) = 10 then
+          for b := 0 to 9 do
+            w_prior2[b] := EnsureRange(StrToInt(sa[b]), 0, 9);
+
+        {sa := parse(config.ReadStr(IntToStr(a), 'w_prior3', ''));
+        if Length(sa) = 10 then
+          for b := 0 to 9 do
+            w_prior3[b] := EnsureRange(StrToInt(sa[b]), 0, 9);}
+      end;
+
+      a += 1;
     end;
 
-    a := a + 1;
+    config.Free();
   end;
 
-  config.Free();
   SetLength(SavedStates, 0);
 end;
 
@@ -1407,6 +1463,20 @@ begin
       Result := Result + 1;
 end;
 
+function g_Bot_GetCount(): Integer;
+var
+  a: Integer;
+begin
+  Result := 0;
+
+  if gPlayers = nil then
+    Exit;
+
+  for a := 0 to High(gPlayers) do
+    if (gPlayers[a] <> nil) and (gPlayers[a] is TBot) then
+      Result := Result + 1;
+end;
+
 function g_Player_GetStats(): TPlayerStatArray;
 var
   a: Integer;
@@ -1459,15 +1529,15 @@ var
 begin
   for i := Low(gPlayers) to High(gPlayers) do
     if (gPlayers[i] <> nil) and gPlayers[i].alive then
-      gPlayers[i].RememberState;
+      gPlayers[i].PreserveState;
 end;
 
 procedure g_Player_ResetAll(Force, Silent: Boolean);
 var
   i: Integer;
 begin
-  gTeamStat[TEAM_RED].Goals := 0;
-  gTeamStat[TEAM_BLUE].Goals := 0;
+  gTeamStat[TEAM_RED].Score := 0;
+  gTeamStat[TEAM_BLUE].Score := 0;
 
   if gPlayers <> nil then
     for i := 0 to High(gPlayers) do
@@ -1997,56 +2067,61 @@ begin
 end;
 
 procedure TPlayer.SetWeaponPrefs(Prefs: Array of Byte);
-var i: Integer;
+var
+  i: Integer;
 begin
   for i := WP_FIRST to WP_LAST + 1 do
     begin
-      if (Prefs[i] < 0) or (Prefs[i] > WP_LAST + 1) then
+      if (Prefs[i] > WP_LAST + 1) then
         FWeapPreferences[i] := 0
-      else FWeapPreferences[i] := Prefs[i];
+      else
+        FWeapPreferences[i] := Prefs[i];
     end;
 end;
 
 procedure TPlayer.SetWeaponPref(Weapon, Pref: Byte);
 begin
-  if (Weapon < 0) or (Weapon > WP_LAST + 1) then
+  if (Weapon > WP_LAST + 1) then
     exit
-  else if (Pref >= 0) and (Pref <= WP_LAST + 1) and (Weapon >= 0) and (Weapon <= WP_LAST + 1) then
+  else if (Pref <= WP_LAST + 1) and (Weapon <= WP_LAST + 1) then
     FWeapPreferences[Weapon] := Pref
-  else if (Weapon >= 0) and (Weapon <= WP_LAST + 1) and ((Pref < 0) or (Pref > WP_LAST + 1)) then
+  else if (Weapon <= WP_LAST + 1) and (Pref > WP_LAST + 1) then
     FWeapPreferences[Weapon] := 0;
 end;
 
 function TPlayer.GetWeaponPref(Weapon: Byte) : Byte;
 begin
-  if (Weapon < 0) or (Weapon > WP_LAST + 1) then
+  if (Weapon > WP_LAST + 1) then
     result := 0
-  else if (FWeapPreferences[Weapon] < 0) or (FWeapPreferences[Weapon] > WP_LAST + 1) then
+  else if (FWeapPreferences[Weapon] > WP_LAST + 1) then
     result := 0
   else
     result := FWeapPreferences[Weapon];
 end;
 
 function TPlayer.GetMorePrefered() : Byte;
-var testedWeap, i: Byte;
+var
+  testedWeap, i: Byte;
 begin
   testedWeap := FCurrWeap;
   for i := WP_FIRST to WP_LAST do
-    if FWeapon[i] and (FWeapPreferences[i] > FWeapPreferences[testedWeap]) then
+    if FWeapon[i] and maySwitch(i) and (FWeapPreferences[i] > FWeapPreferences[testedWeap]) then
       testedWeap := i;
-  if (R_BERSERK in FRulez) and (FWeapPreferences[WP_LAST + 1] > FWeapPreferences[testedWeap]) then
-    testedWeap := WEAPON_KASTET;
+  if (R_BERSERK in FInventory) and (FWeapPreferences[WP_LAST + 1] > FWeapPreferences[testedWeap]) then
+    testedWeap := WEAPON_IRONFIST;
   result := testedWeap;
 end;
 
 function TPlayer.maySwitch(Weapon: Byte) : Boolean;
 begin
   result := true;
-  if (Weapon = WEAPON_KASTET) and (FSkipFist <> 0) then
-    if (FSkipFist = 1) and (not (R_BERSERK in FRulez)) then
-      result := false
-  else if (FSwitchToEmpty = 0) and not hasAmmoForWeapon(Weapon) then
-    result := false
+  if (Weapon = WEAPON_IRONFIST) and (FSkipIronFist <> 0) then
+  begin
+    if (FSkipIronFist = 1) and (not (R_BERSERK in FInventory)) then
+      result := false;
+  end
+  else if (FSwitchToEmpty = 0) and (not hasAmmoForShooting(Weapon)) then
+    result := false;
 end;
 
 procedure TPlayer.SwitchTeam;
@@ -2110,12 +2185,12 @@ begin
     if not PickItem(ItemType, gItems[i].Respawnable, r) then Continue;
 
     if ItemType in [ITEM_SPHERE_BLUE, ITEM_SPHERE_WHITE, ITEM_INVUL] then
-     g_Sound_PlayExAt('SOUND_ITEM_GETRULEZ', FObj.X, FObj.Y)
+     g_Sound_PlayExAt('SOUND_ITEM_GETPOWERUP', FObj.X, FObj.Y)
     else if ItemType in [ITEM_MEDKIT_SMALL, ITEM_MEDKIT_LARGE, ITEM_MEDKIT_BLACK] then
      g_Sound_PlayExAt('SOUND_ITEM_GETMED', FObj.X, FObj.Y)
     else g_Sound_PlayExAt('SOUND_ITEM_GETITEM', FObj.X, FObj.Y);
 
-    // Íàäî óáðàòü ñ êàðòû, åñëè ýòî íå êëþ÷, êîòîðûì íóæíî ïîäåëèòñÿ ñ äðóãèì èãðîêîì:
+    // Íàäî óáðàòü ñ êàðòû, åñëè ýòî íå êëþ÷, êîòîðûì íóæíî ïîäåëèòüñÿ ñ äðóãèì èãðîêîì:
     if r and not ((ItemType in [ITEM_KEY_RED, ITEM_KEY_GREEN, ITEM_KEY_BLUE]) and
                   (gGameSettings.GameType = GT_SINGLE) and
                   (g_Player_GetCount() > 1)) then
@@ -2232,15 +2307,15 @@ begin
       end;
     end;
     // Îáíóëèòü äåéñòâèÿ ïðèìî÷åê, ÷òîáû ôîí ïðîïàë
-    FMegaRulez[MR_SUIT] := 0;
-    FMegaRulez[MR_INVUL] := 0;
-    FMegaRulez[MR_INVIS] := 0;
+    FPowerups[MR_SUIT] := 0;
+    FPowerups[MR_INVUL] := 0;
+    FPowerups[MR_INVIS] := 0;
     FSpawnInvul := 0;
     FBerserk := 0;
   end;
 
 // Íî îò îñòàëüíîãî ñïàñàåò:
-  if FMegaRulez[MR_INVUL] >= gTime then
+  if FPowerups[MR_INVUL] >= gTime then
     Exit;
 
 // ×èò-êîä "ÃÎÐÅÖ":
@@ -2248,7 +2323,7 @@ begin
     Exit;
 
 // Åñëè åñòü óðîí ñâîèì, èëè ðàíèë ñàì ñåáÿ, èëè òåáÿ ðàíèë ïðîòèâíèê:
-  if LongBool(gGameSettings.Options and GAME_OPTION_TEAMDAMAGE) or
+  if (TGameOption.TEAM_DAMAGE in gGameSettings.Options) or
      (SpawnerUID = FUID) or
      (not SameTeam(FUID, SpawnerUID)) then
   begin
@@ -2272,8 +2347,8 @@ begin
         end;
 
       if t = HIT_WATER then
-        g_GFX_Bubbles(FObj.X+PLAYER_RECT.X+(PLAYER_RECT.Width div 2),
-                      FObj.Y+PLAYER_RECT.Y-4, value div 2, 8, 4);
+        g_Game_Effect_Bubbles(FObj.X+PLAYER_RECT.X+(PLAYER_RECT.Width div 2),
+                              FObj.Y+PLAYER_RECT.Y-4, value div 2, 8, 4);
     end;
 
   // Áóôåð óðîíà:
@@ -2528,7 +2603,7 @@ begin
       end;
     end;
 
-    if (FMegaRulez[MR_INVUL] > gTime) and ((gPlayerDrawn <> Self) or (FSpawnInvul >= gTime)) then
+    if (FPowerups[MR_INVUL] > gTime) and ((gPlayerDrawn <> Self) or (FSpawnInvul >= gTime)) then
       if g_Texture_Get('TEXTURE_PLAYER_INVULPENTA', ID) then
       begin
         e_GetTextureSize(ID, @w, @h);
@@ -2540,13 +2615,13 @@ begin
                      fY+FObj.Rect.Y+(FObj.Rect.Height div 2)-(h div 2)-7+fSlope, 0, True, False);
       end;
 
-    if FMegaRulez[MR_INVIS] > gTime then
+    if FPowerups[MR_INVIS] > gTime then
     begin
       if (gPlayerDrawn <> nil) and ((Self = gPlayerDrawn) or
          ((FTeam = gPlayerDrawn.Team) and (gGameSettings.GameMode <> GM_DM))) then
       begin
-        if (FMegaRulez[MR_INVIS] - gTime) <= 2100 then
-          dr := not Odd((FMegaRulez[MR_INVIS] - gTime) div 300)
+        if (FPowerups[MR_INVIS] - gTime) <= 2100 then
+          dr := not Odd((FPowerups[MR_INVIS] - gTime) div 300)
         else
           dr := True;
         if dr then
@@ -2555,7 +2630,7 @@ begin
           FModel.Draw(fX, fY+fSlope);
       end
       else
-        FModel.Draw(fX, fY+fSlope, 254);
+        FModel.Draw(fX, fY+fSlope, 255);
     end
     else
       FModel.Draw(fX, fY+fSlope);
@@ -2571,7 +2646,7 @@ begin
   end;
 
   if (gChatBubble > 0) and (FKeys[KEY_CHAT].Pressed) and not FGhost then
-    if (FMegaRulez[MR_INVIS] <= gTime) or ((gPlayerDrawn <> nil) and ((Self = gPlayerDrawn) or
+    if (FPowerups[MR_INVIS] <= gTime) or ((gPlayerDrawn <> nil) and ((Self = gPlayerDrawn) or
        ((FTeam = gPlayerDrawn.Team) and (gGameSettings.GameMode <> GM_DM)))) then
       DrawBubble();
  // e_DrawPoint(5, 335, 288, 255, 0, 0); // DL, UR, DL, UR
@@ -2711,7 +2786,7 @@ begin
   SY := gPlayerScreenSize.Y;
   Y := 0;
 
-  if gShowGoals and (gGameSettings.GameMode in [GM_TDM, GM_CTF]) then
+  if gShowScore and (gGameSettings.GameMode in [GM_TDM, GM_CTF]) then
   begin
     if gGameSettings.GameMode = GM_CTF then
       a := 32 + 8
@@ -2728,7 +2803,7 @@ begin
         e_Draw(ID, X-16-32, 240-72-4, 0, True, False);
     end;
 
-    s := IntToStr(gTeamStat[TEAM_RED].Goals);
+    s := IntToStr(gTeamStat[TEAM_RED].Score);
     e_CharFont_GetSize(gMenuFont, s, tw, th);
     e_CharFont_PrintEx(gMenuFont, X-16-a-tw, 240-72-4, s, TEAMCOLOR[TEAM_RED]);
 
@@ -2743,7 +2818,7 @@ begin
         e_Draw(ID,  X-16-32, 240-32-4, 0, True, False);
     end;
 
-    s := IntToStr(gTeamStat[TEAM_BLUE].Goals);
+    s := IntToStr(gTeamStat[TEAM_BLUE].Score);
     e_CharFont_GetSize(gMenuFont, s, tw, th);
     e_CharFont_PrintEx(gMenuFont, X-16-a-tw, 240-32-4, s, TEAMCOLOR[TEAM_BLUE]);
   end;
@@ -2805,10 +2880,9 @@ begin
   e_CharFont_GetSize(gMenuSmallFont, FName, tw, th);
   e_CharFont_PrintEx(gMenuSmallFont, X+98-(tw div 2), Y+8, FName, _RGB(255, 0, 0));
 
-  if R_BERSERK in FRulez then
-    e_Draw(gItemsTexturesID[ITEM_MEDKIT_BLACK], X+37, Y+45, 0, True, False)
-  else
-    e_Draw(gItemsTexturesID[ITEM_MEDKIT_LARGE], X+37, Y+45, 0, True, False);
+  if R_BERSERK in FInventory
+    then e_Draw(gItemsTexturesID[ITEM_MEDKIT_BLACK], X+37, Y+45, 0, True, False)
+    else e_Draw(gItemsTexturesID[ITEM_MEDKIT_LARGE], X+37, Y+45, 0, True, False);
 
   if g_Texture_Get('TEXTURE_PLAYER_ARMORHUD', ID) then
     e_Draw(ID, X+36, Y+77, 0, True, False);
@@ -2824,10 +2898,10 @@ begin
   s := IntToStr(GetAmmoByWeapon(FCurrWeap));
 
   case FCurrWeap of
-    WEAPON_KASTET:
+    WEAPON_IRONFIST:
     begin
       s := '--';
-      ID := gItemsTexturesID[ITEM_WEAPON_KASTET];
+      ID := gItemsTexturesID[ITEM_WEAPON_IRONFIST];
     end;
     WEAPON_SAW:
     begin
@@ -2838,7 +2912,7 @@ begin
     WEAPON_CHAINGUN: ID := gItemsTexturesID[ITEM_WEAPON_CHAINGUN];
     WEAPON_SHOTGUN1: ID := gItemsTexturesID[ITEM_WEAPON_SHOTGUN1];
     WEAPON_SHOTGUN2: ID := gItemsTexturesID[ITEM_WEAPON_SHOTGUN2];
-    WEAPON_SUPERPULEMET: ID := gItemsTexturesID[ITEM_WEAPON_SUPERPULEMET];
+    WEAPON_SUPERCHAINGUN: ID := gItemsTexturesID[ITEM_WEAPON_SUPERCHAINGUN];
     WEAPON_ROCKETLAUNCHER: ID := gItemsTexturesID[ITEM_WEAPON_ROCKETLAUNCHER];
     WEAPON_PLASMA: ID := gItemsTexturesID[ITEM_WEAPON_PLASMA];
     WEAPON_BFG: ID := gItemsTexturesID[ITEM_WEAPON_BFG];
@@ -2849,13 +2923,13 @@ begin
   e_CharFont_PrintEx(gMenuFont, X+178-tw, Y+158, s, _RGB(255, 0, 0));
   e_Draw(ID, X+20, Y+160, 0, True, False);
 
-  if R_KEY_RED in FRulez then
+  if R_KEY_RED in FInventory then
     e_Draw(gItemsTexturesID[ITEM_KEY_RED], X+78, Y+214, 0, True, False);
 
-  if R_KEY_GREEN in FRulez then
+  if R_KEY_GREEN in FInventory then
     e_Draw(gItemsTexturesID[ITEM_KEY_GREEN], X+95, Y+214, 0, True, False);
 
-  if R_KEY_BLUE in FRulez then
+  if R_KEY_BLUE in FInventory then
     e_Draw(gItemsTexturesID[ITEM_KEY_BLUE], X+112, Y+214, 0, True, False);
 
   if FJetFuel > 0 then
@@ -2898,15 +2972,15 @@ begin
   end;
 end;
 
-procedure TPlayer.DrawRulez();
+procedure TPlayer.DrawOverlay();
 var
   dr: Boolean;
 begin
   // Ïðè âçÿòèè íåóÿçâèìîñòè ðèñóåòñÿ èíâåðñèîííûé áåëûé ôîí
-  if (FMegaRulez[MR_INVUL] >= gTime) and (FSpawnInvul < gTime) then
+  if (FPowerups[MR_INVUL] >= gTime) and (FSpawnInvul < gTime) then
   begin
-    if (FMegaRulez[MR_INVUL]-gTime) <= 2100 then
-      dr := not Odd((FMegaRulez[MR_INVUL]-gTime) div 300)
+    if (FPowerups[MR_INVUL]-gTime) <= 2100 then
+      dr := not Odd((FPowerups[MR_INVUL]-gTime) div 300)
     else
       dr := True;
 
@@ -2916,10 +2990,10 @@ begin
   end;
 
   // Ïðè âçÿòèè çàùèòíîãî êîñòþìà ðèñóåòñÿ çåëåíîâàòûé ôîí
-  if FMegaRulez[MR_SUIT] >= gTime then
+  if FPowerups[MR_SUIT] >= gTime then
   begin
-    if (FMegaRulez[MR_SUIT]-gTime) <= 2100 then
-      dr := not Odd((FMegaRulez[MR_SUIT]-gTime) div 300)
+    if (FPowerups[MR_SUIT]-gTime) <= 2100 then
+      dr := not Odd((FPowerups[MR_SUIT]-gTime) div 300)
     else
       dr := True;
 
@@ -2985,7 +3059,7 @@ begin
     FPunchAnim := nil;
   end;
   st := 'FRAMES_PUNCH';
-  if R_BERSERK in FRulez then
+  if R_BERSERK in FInventory then
     st := st + '_BERSERK';
   if FKeys[KEY_UP].Pressed then
     st := st + '_UP'
@@ -3022,10 +3096,10 @@ begin
   yd := wy+firediry();
 
   case FCurrWeap of
-    WEAPON_KASTET:
+    WEAPON_IRONFIST:
     begin
       DoPunch();
-      if R_BERSERK in FRulez then
+      if R_BERSERK in FInventory then
       begin
         //g_Weapon_punch(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y, 75, FUID);
         locobj.X := FObj.X+FObj.Rect.X;
@@ -3161,7 +3235,7 @@ begin
         DidFire := True;
       end;
 
-    WEAPON_SUPERPULEMET:
+    WEAPON_SUPERCHAINGUN:
       if FAmmo[A_SHELLS] > 0 then
       begin
         g_Weapon_shotgun(wx, wy, xd, yd, FUID);
@@ -3218,7 +3292,7 @@ function TPlayer.GetAmmoByWeapon(Weapon: Byte): Word;
 begin
   case Weapon of
     WEAPON_PISTOL, WEAPON_CHAINGUN: Result := FAmmo[A_BULLETS];
-    WEAPON_SHOTGUN1, WEAPON_SHOTGUN2, WEAPON_SUPERPULEMET: Result := FAmmo[A_SHELLS];
+    WEAPON_SHOTGUN1, WEAPON_SHOTGUN2, WEAPON_SUPERCHAINGUN: Result := FAmmo[A_SHELLS];
     WEAPON_ROCKETLAUNCHER: Result := FAmmo[A_ROCKETS];
     WEAPON_PLASMA, WEAPON_BFG: Result := FAmmo[A_CELLS];
     WEAPON_FLAMETHROWER: Result := FAmmo[A_FUEL];
@@ -3283,7 +3357,7 @@ 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
+  if (FPowerups[MR_SUIT] > gTime) or (FPowerups[MR_INVUL] > gTime) then
     exit; // Íå çàãîðàåìñÿ êîãäà åñòü çàùèòà
   if g_Obj_CollidePanel(@FObj, 0, 0, PANEL_WATER or PANEL_ACID1 or PANEL_ACID2) then
     exit; // Íå ïîäãîðàåì â âîäå íà âñÿêèé ñëó÷àé
@@ -3452,7 +3526,7 @@ begin
       if Srv then
       begin
         if gGameSettings.GameMode = GM_TDM then
-          Dec(gTeamStat[FTeam].Goals);
+          Dec(gTeamStat[FTeam].Score);
         if DoFrags or (gGameSettings.GameMode = GM_TDM) then
         begin
           Dec(FFrags);
@@ -3479,7 +3553,7 @@ begin
             end;
 
           if (gGameSettings.GameMode = GM_TDM) and DoFrags then
-            Inc(gTeamStat[KP.Team].Goals,
+            Inc(gTeamStat[KP.Team].Score,
               IfThen(SameTeam(FUID, SpawnerUID), -1, 1));
 
           if netsrv then MH_SEND_PlayerStats(SpawnerUID);
@@ -3554,7 +3628,7 @@ begin
           WEAPON_ROCKETLAUNCHER: i := ITEM_WEAPON_ROCKETLAUNCHER;
           WEAPON_PLASMA: i := ITEM_WEAPON_PLASMA;
           WEAPON_BFG: i := ITEM_WEAPON_BFG;
-          WEAPON_SUPERPULEMET: i := ITEM_WEAPON_SUPERPULEMET;
+          WEAPON_SUPERCHAINGUN: i := ITEM_WEAPON_SUPERCHAINGUN;
           WEAPON_FLAMETHROWER: i := ITEM_WEAPON_FLAMETHROWER;
           else i := 0;
         end;
@@ -3564,7 +3638,7 @@ begin
       end;
 
 // Âûáðîñ ðþêçàêà:
-    if R_ITEM_BACKPACK in FRulez then
+    if R_ITEM_BACKPACK in FInventory then
       PushItem(ITEM_AMMO_BACKPACK);
 
 // Âûáðîñ ðàêåòíîãî ðàíöà:
@@ -3573,15 +3647,15 @@ begin
 
 // Âûáðîñ êëþ÷åé:
     if (not (gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF])) or
-       (not LongBool(gGameSettings.Options and GAME_OPTION_DMKEYS)) then
+       (not (TGameOption.DM_KEYS in gGameSettings.Options)) then
     begin
-      if R_KEY_RED in FRulez then
+      if R_KEY_RED in FInventory then
         PushItem(ITEM_KEY_RED);
 
-      if R_KEY_GREEN in FRulez then
+      if R_KEY_GREEN in FInventory then
         PushItem(ITEM_KEY_GREEN);
 
-      if R_KEY_BLUE in FRulez then
+      if R_KEY_BLUE in FInventory then
         PushItem(ITEM_KEY_BLUE);
     end;
 
@@ -3640,7 +3714,7 @@ begin
         g_Game_Message(Format(_lc[I_MESSAGE_TLMS_WIN], [AnsiUpperCase(_lc[I_GAME_TEAM_RED])]), 144);
         if Netsrv then
           MH_SEND_GameEvent(NET_EV_TLMS_WIN, TEAM_RED);
-        Inc(gTeamStat[TEAM_RED].Goals);
+        Inc(gTeamStat[TEAM_RED].Score);
         gLMSRespawn := LMS_RESPAWN_FINAL;
         gLMSRespawnTime := gTime + 5000;
       end
@@ -3650,7 +3724,7 @@ begin
         g_Game_Message(Format(_lc[I_MESSAGE_TLMS_WIN], [AnsiUpperCase(_lc[I_GAME_TEAM_BLUE])]), 144);
         if Netsrv then
           MH_SEND_GameEvent(NET_EV_TLMS_WIN, TEAM_BLUE);
-        Inc(gTeamStat[TEAM_BLUE].Goals);
+        Inc(gTeamStat[TEAM_BLUE].Score);
         gLMSRespawn := LMS_RESPAWN_FINAL;
         gLMSRespawnTime := gTime + 5000;
       end
@@ -3768,8 +3842,8 @@ function TPlayer.hasAmmoForWeapon (weapon: Byte): Boolean;
 begin
   result := false;
   case weapon of
-    WEAPON_KASTET, WEAPON_SAW: result := true;
-    WEAPON_SHOTGUN1, WEAPON_SHOTGUN2, WEAPON_SUPERPULEMET: result := (FAmmo[A_SHELLS] > 0);
+    WEAPON_IRONFIST, WEAPON_SAW: result := true;
+    WEAPON_SHOTGUN1, WEAPON_SHOTGUN2, WEAPON_SUPERCHAINGUN: result := (FAmmo[A_SHELLS] > 0);
     WEAPON_PISTOL, WEAPON_CHAINGUN: result := (FAmmo[A_BULLETS] > 0);
     WEAPON_ROCKETLAUNCHER: result := (FAmmo[A_ROCKETS] > 0);
     WEAPON_PLASMA, WEAPON_BFG: result := (FAmmo[A_CELLS] > 0);
@@ -3778,10 +3852,26 @@ begin
   end;
 end;
 
+function TPlayer.hasAmmoForShooting (weapon: Byte): Boolean;
+begin
+  result := false;
+  case weapon of
+    WEAPON_IRONFIST, WEAPON_SAW: result := true;
+    WEAPON_SHOTGUN1, WEAPON_SUPERCHAINGUN: result := (FAmmo[A_SHELLS] > 0);
+    WEAPON_SHOTGUN2: result := (FAmmo[A_SHELLS] > 1);
+    WEAPON_PISTOL, WEAPON_CHAINGUN: result := (FAmmo[A_BULLETS] > 0);
+    WEAPON_ROCKETLAUNCHER: result := (FAmmo[A_ROCKETS] > 0);
+    WEAPON_PLASMA: result := (FAmmo[A_CELLS] > 0);
+    WEAPON_BFG: result := (FAmmo[A_CELLS] >= 40);
+    WEAPON_FLAMETHROWER: result := (FAmmo[A_FUEL] > 0);
+    else result := (weapon < length(FWeapon));
+  end;
+end;
+
 function TPlayer.shouldSwitch (weapon: Byte; hadWeapon: Boolean): Boolean;
 begin
   result := false;
-  if (weapon < 0) or (weapon > WP_LAST + 1) then
+  if (weapon > WP_LAST + 1) then
     begin
       result := false;
       exit;
@@ -3956,26 +4046,16 @@ begin
 end;
 
 function TPlayer.PickItem(ItemType: Byte; arespawn: Boolean; var remove: Boolean): Boolean;
-
-  function allowBerserkSwitching (): Boolean;
-  begin
-    if (FBFGFireCounter <> -1) then begin result := false; exit; end;
-    result := true;
-    if gBerserkAutoswitch then exit;
-    if not conIsCheatsEnabled then exit;
-    result := false;
-  end;
-
 var
   a: Boolean;
-  switchWeapon: Byte = -1;
+  switchWeapon: Byte = 255;
   hadWeapon: Boolean = False;
 begin
   Result := False;
   if g_Game_IsClient then Exit;
 
   // a = true - ìåñòî ñïàâíà ïðåäìåòà:
-  a := LongBool(gGameSettings.Options and GAME_OPTION_WEAPONSTAY) and arespawn;
+  a := (TGameOption.WEAPONS_STAY in gGameSettings.Options) and arespawn;
   remove := not a;
   case ItemType of
     ITEM_MEDKIT_SMALL:
@@ -4129,14 +4209,14 @@ begin
         if a and g_Game_IsNet then MH_SEND_Sound(GameX, GameY, 'SOUND_ITEM_GETWEAPON');
       end;
 
-    ITEM_WEAPON_SUPERPULEMET:
-      if (FAmmo[A_SHELLS] < FMaxAmmo[A_SHELLS]) or not FWeapon[WEAPON_SUPERPULEMET] then
+    ITEM_WEAPON_SUPERCHAINGUN:
+      if (FAmmo[A_SHELLS] < FMaxAmmo[A_SHELLS]) or not FWeapon[WEAPON_SUPERCHAINGUN] then
       begin
-        if a and FWeapon[WEAPON_SUPERPULEMET] then Exit;
-        switchWeapon := WEAPON_SUPERPULEMET;
-        hadWeapon := FWeapon[WEAPON_SUPERPULEMET];
+        if a and FWeapon[WEAPON_SUPERCHAINGUN] then Exit;
+        switchWeapon := WEAPON_SUPERCHAINGUN;
+        hadWeapon := FWeapon[WEAPON_SUPERCHAINGUN];
         IncMax(FAmmo[A_SHELLS], 4, FMaxAmmo[A_SHELLS]);
-        FWeapon[WEAPON_SUPERPULEMET] := True;
+        FWeapon[WEAPON_SUPERCHAINGUN] := True;
         Result := True;
         if gFlash = 2 then Inc(FPickup, 5);
         if a and g_Game_IsNet then MH_SEND_Sound(GameX, GameY, 'SOUND_ITEM_GETWEAPON');
@@ -4237,7 +4317,7 @@ begin
       end;
 
     ITEM_AMMO_BACKPACK:
-      if not(R_ITEM_BACKPACK in FRulez) or
+      if not(R_ITEM_BACKPACK in FInventory) or
             (FAmmo[A_BULLETS] < FMaxAmmo[A_BULLETS]) or
             (FAmmo[A_SHELLS] < FMaxAmmo[A_SHELLS]) or
             (FAmmo[A_ROCKETS] < FMaxAmmo[A_ROCKETS]) or
@@ -4261,16 +4341,16 @@ begin
         if FAmmo[A_FUEL] < FMaxAmmo[A_FUEL] then
           IncMax(FAmmo[A_FUEL], 50, FMaxAmmo[A_FUEL]);
 
-        FRulez := FRulez + [R_ITEM_BACKPACK];
+        FInventory += [R_ITEM_BACKPACK];
         Result := True;
         remove := True;
-        if gFlash = 2 then Inc(FPickup, 5);
+        if gFlash = 2 then FPickup += 5;
       end;
 
     ITEM_KEY_RED:
-      if not(R_KEY_RED in FRulez) then
+      if not(R_KEY_RED in FInventory) then
       begin
-        Include(FRulez, R_KEY_RED);
+        FInventory += [R_KEY_RED];
         Result := True;
         remove := (gGameSettings.GameMode <> GM_COOP) and (g_Player_GetCount() < 2);
         if gFlash = 2 then Inc(FPickup, 5);
@@ -4278,9 +4358,9 @@ begin
       end;
 
     ITEM_KEY_GREEN:
-      if not(R_KEY_GREEN in FRulez) then
+      if not(R_KEY_GREEN in FInventory) then
       begin
-        Include(FRulez, R_KEY_GREEN);
+        FInventory += [R_KEY_GREEN];
         Result := True;
         remove := (gGameSettings.GameMode <> GM_COOP) and (g_Player_GetCount() < 2);
         if gFlash = 2 then Inc(FPickup, 5);
@@ -4288,9 +4368,9 @@ begin
       end;
 
     ITEM_KEY_BLUE:
-      if not(R_KEY_BLUE in FRulez) then
+      if not(R_KEY_BLUE in FInventory) then
       begin
-        Include(FRulez, R_KEY_BLUE);
+        FInventory += [R_KEY_BLUE];
         Result := True;
         remove := (gGameSettings.GameMode <> GM_COOP) and (g_Player_GetCount() < 2);
         if gFlash = 2 then Inc(FPickup, 5);
@@ -4298,9 +4378,9 @@ begin
       end;
 
     ITEM_SUIT:
-      if FMegaRulez[MR_SUIT] < gTime+PLAYER_SUIT_TIME then
+      if FPowerups[MR_SUIT] < gTime+PLAYER_SUIT_TIME then
       begin
-        FMegaRulez[MR_SUIT] := gTime+PLAYER_SUIT_TIME;
+        FPowerups[MR_SUIT] := gTime+PLAYER_SUIT_TIME;
         Result := True;
         remove := True;
         FFireTime := 0;
@@ -4318,14 +4398,18 @@ begin
 
     ITEM_MEDKIT_BLACK:
       begin
-        if not (R_BERSERK in FRulez) then
+        if not (R_BERSERK in FInventory) then
         begin
-          Include(FRulez, R_BERSERK);
-          if (shouldSwitch(WP_LAST + 1, false)) then
-            QueueWeaponSwitch(WEAPON_KASTET);
+          FInventory += [R_BERSERK];
+          if (FBFGFireCounter = -1) then
+          begin
+            FCurrWeap := WEAPON_IRONFIST;
+            resetWeaponQueue();
+            FModel.SetWeapon(WEAPON_IRONFIST);
+          end;
           if gFlash <> 0 then
           begin
-            Inc(FPain, 100);
+            FPain += 100;
             if gFlash = 2 then Inc(FPickup, 5);
           end;
           FBerserk := gTime+30000;
@@ -4344,9 +4428,9 @@ begin
       end;
 
     ITEM_INVUL:
-      if FMegaRulez[MR_INVUL] < gTime+PLAYER_INVUL_TIME then
+      if FPowerups[MR_INVUL] < gTime+PLAYER_INVUL_TIME then
       begin
-        FMegaRulez[MR_INVUL] := gTime+PLAYER_INVUL_TIME;
+        FPowerups[MR_INVUL] := gTime+PLAYER_INVUL_TIME;
         FSpawnInvul := 0;
         Result := True;
         remove := True;
@@ -4382,9 +4466,9 @@ begin
       end;
 
     ITEM_INVIS:
-      if FMegaRulez[MR_INVIS] < gTime+PLAYER_INVIS_TIME then
+      if FPowerups[MR_INVIS] < gTime+PLAYER_INVIS_TIME then
       begin
-        FMegaRulez[MR_INVIS] := gTime+PLAYER_INVIS_TIME;
+        FPowerups[MR_INVIS] := gTime+PLAYER_INVIS_TIME;
         Result := True;
         remove := True;
         if gFlash = 2 then Inc(FPickup, 5);
@@ -4582,12 +4666,12 @@ begin
   if (gGameSettings.GameType <> GT_SINGLE) and (gGameSettings.GameMode <> GM_COOP) then
     begin // "Ñâîÿ èãðà"
     // Áåðñåðê íå ñîõðàíÿåòñÿ ìåæäó óðîâíÿìè:
-      FRulez := FRulez-[R_BERSERK];
+      FInventory -= [R_BERSERK];
     end
   else // "Îäèíî÷íàÿ èãðà"/"Êîîï"
     begin
     // Áåðñåðê è êëþ÷è íå ñîõðàíÿþòñÿ ìåæäó óðîâíÿìè:
-      FRulez := FRulez-[R_KEY_RED, R_KEY_GREEN, R_KEY_BLUE, R_BERSERK];
+      FInventory -= [R_KEY_RED, R_KEY_GREEN, R_KEY_BLUE, R_BERSERK];
     end;
 
 // Ïîëó÷àåì òî÷êó ñïàóíà èãðîêà:
@@ -4612,7 +4696,7 @@ begin
     end;
 
     FWeapon[WEAPON_PISTOL] := True;
-    FWeapon[WEAPON_KASTET] := True;
+    FWeapon[WEAPON_IRONFIST] := True;
     FCurrWeap := WEAPON_PISTOL;
     resetWeaponQueue();
 
@@ -4630,10 +4714,10 @@ begin
     FMaxAmmo[A_FUEL] := AmmoLimits[0, A_FUEL];
 
     if (gGameSettings.GameMode in [GM_DM, GM_TDM, GM_CTF]) and
-       LongBool(gGameSettings.Options and GAME_OPTION_DMKEYS) then
-      FRulez := [R_KEY_RED, R_KEY_GREEN, R_KEY_BLUE]
+       (TGameOption.DM_KEYS in gGameSettings.Options) then
+      FInventory := [R_KEY_RED, R_KEY_GREEN, R_KEY_BLUE]
     else
-      FRulez := [];
+      FInventory := [];
   end;
 
 // Ïîëó÷àåì êîîðäèíàòû òî÷êè âîçðîæäåíèÿ:
@@ -4665,14 +4749,14 @@ begin
   for a := Low(FTime) to High(FTime) do
     FTime[a] := 0;
 
-  for a := Low(FMegaRulez) to High(FMegaRulez) do
-    FMegaRulez[a] := 0;
+  for a := Low(FPowerups) to High(FPowerups) do
+    FPowerups[a] := 0;
 
 // Respawn invulnerability
   if (gGameSettings.GameType <> GT_SINGLE) and (gGameSettings.SpawnInvul > 0) then
   begin
-    FMegaRulez[MR_INVUL] := gTime + gGameSettings.SpawnInvul * 1000;
-    FSpawnInvul := FMegaRulez[MR_INVUL];
+    FPowerups[MR_INVUL] := gTime + gGameSettings.SpawnInvul * 1000;
+    FSpawnInvul := FPowerups[MR_INVUL];
   end;
 
   FDamageBuffer := 0;
@@ -5247,9 +5331,9 @@ begin
   if FAlive and (FObj.Y > Integer(gMapInfo.Height)+128) and AnyServer then
   begin
     // Îáíóëèòü äåéñòâèÿ ïðèìî÷åê, ÷òîáû ôîí ïðîïàë
-    FMegaRulez[MR_SUIT] := 0;
-    FMegaRulez[MR_INVUL] := 0;
-    FMegaRulez[MR_INVIS] := 0;
+    FPowerups[MR_SUIT] := 0;
+    FPowerups[MR_INVUL] := 0;
+    FPowerups[MR_INVIS] := 0;
     Kill(K_FALLKILL, 0, HIT_FALL);
   end;
 
@@ -5317,7 +5401,7 @@ begin
         else
           Dec(FBFGFireCounter);
 
-    if (FMegaRulez[MR_SUIT] < gTime) and AnyServer then
+    if (FPowerups[MR_SUIT] < gTime) and AnyServer then
     begin
       b := g_GetAcidHit(FObj.X+PLAYER_RECT.X, FObj.Y+PLAYER_RECT.Y, PLAYER_RECT.Width, PLAYER_RECT.Height);
 
@@ -5334,13 +5418,8 @@ begin
           FAir := 0;
       end
       else if (FAir mod 31 = 0) and not blockmon then
-      begin
-        g_GFX_Bubbles(FObj.X+PLAYER_RECT.X+(PLAYER_RECT.Width div 2), FObj.Y+PLAYER_RECT.Y-4, 5+Random(6), 8, 4);
-        if Random(2) = 0 then
-          g_Sound_PlayExAt('SOUND_GAME_BUBBLE1', FObj.X, FObj.Y)
-        else
-          g_Sound_PlayExAt('SOUND_GAME_BUBBLE2', FObj.X, FObj.Y);
-      end;
+        g_Game_Effect_Bubbles(FObj.X+PLAYER_RECT.X+(PLAYER_RECT.Width div 2),
+                              FObj.Y+PLAYER_RECT.Y-4, 5+Random(6), 8, 4);
     end else if FAir < AIR_DEF then
       FAir := AIR_DEF;
 
@@ -5351,9 +5430,9 @@ begin
         FFireTime := 0;
         FFirePainTime := 0;
       end
-      else if FMegaRulez[MR_SUIT] >= gTime then
+      else if FPowerups[MR_SUIT] >= gTime then
       begin
-        if FMegaRulez[MR_SUIT] = gTime then
+        if FPowerups[MR_SUIT] = gTime then
           FFireTime := 1;
         FFirePainTime := 0;
       end
@@ -5368,7 +5447,7 @@ begin
         end;
         FFirePainTime := FFirePainTime - 1;
         FFireTime := FFireTime - 1;
-        if ((FFireTime mod 33) = 0) and (FMegaRulez[MR_INVUL] < gTime) then
+        if ((FFireTime mod 33) = 0) and (FPowerups[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);
@@ -5480,7 +5559,7 @@ begin
             (y >= 0) and (y <= PLAYER_RECT.Height);
 end;
 
-function g_Player_ValidName(Name: string): Boolean;
+function g_Player_ExistingName(Name: string): Boolean;
 var
   a: Integer;
 begin
@@ -5513,9 +5592,9 @@ function TPlayer.GetKeys(): Byte;
 begin
   Result := 0;
 
-  if R_KEY_RED in FRulez then Result := KEY_RED;
-  if R_KEY_GREEN in FRulez then Result := Result or KEY_GREEN;
-  if R_KEY_BLUE in FRulez then Result := Result or KEY_BLUE;
+  if R_KEY_RED in FInventory then Result := Result or KEY_RED;
+  if R_KEY_GREEN in FInventory then Result := Result or KEY_GREEN;
+  if R_KEY_BLUE in FInventory then Result := Result or KEY_BLUE;
 
   if FTeam = TEAM_RED then Result := Result or KEY_REDTEAM;
   if FTeam = TEAM_BLUE then Result := Result or KEY_BLUETEAM;
@@ -5547,20 +5626,20 @@ end;
 procedure TPlayer.NetFire(Wpn: Byte; X, Y, AX, AY: Integer; WID: Integer = -1);
 var
   locObj: TObj;
-  F: Boolean;
+  visible: Boolean = True;
   WX, WY, XD, YD: Integer;
 begin
-  F := False;
   WX := X;
   WY := Y;
   XD := AX;
   YD := AY;
 
   case FCurrWeap of
-    WEAPON_KASTET:
+    WEAPON_IRONFIST:
     begin
+      visible := False;
       DoPunch();
-      if R_BERSERK in FRulez then
+      if R_BERSERK in FInventory then
       begin
         //g_Weapon_punch(FObj.X+FObj.Rect.X, FObj.Y+FObj.Rect.Y, 75, FUID);
         locobj.X := FObj.X+FObj.Rect.X;
@@ -5600,14 +5679,12 @@ begin
         FSawSoundSelect.Stop();
         FSawSound.PlayAt(FObj.X, FObj.Y);
       end;
-      f := True;
     end;
 
     WEAPON_PISTOL:
     begin
       g_Sound_PlayExAt('SOUND_WEAPON_FIREPISTOL', GameX, Gamey);
       FFireAngle := FAngle;
-      f := True;
       g_Player_CreateShell(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX,
                              GameVelX, GameVelY-2, SHELL_BULLET);
     end;
@@ -5616,7 +5693,6 @@ begin
     begin
       g_Sound_PlayExAt('SOUND_WEAPON_FIRESHOTGUN', Gamex, Gamey);
       FFireAngle := FAngle;
-      f := True;
       FShellTimer := 10;
       FShellType := SHELL_SHELL;
     end;
@@ -5625,7 +5701,6 @@ begin
     begin
       g_Sound_PlayExAt('SOUND_WEAPON_FIRESHOTGUN2', Gamex, Gamey);
       FFireAngle := FAngle;
-      f := True;
       FShellTimer := 13;
       FShellType := SHELL_DBLSHELL;
     end;
@@ -5634,7 +5709,6 @@ begin
     begin
       g_Sound_PlayExAt('SOUND_WEAPON_FIRECGUN', Gamex, Gamey);
       FFireAngle := FAngle;
-      f := True;
       g_Player_CreateShell(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX,
                              GameVelX, GameVelY-2, SHELL_BULLET);
     end;
@@ -5643,28 +5717,24 @@ begin
     begin
       g_Weapon_Rocket(wx, wy, xd, yd, FUID, WID);
       FFireAngle := FAngle;
-      f := True;
     end;
 
     WEAPON_PLASMA:
     begin
       g_Weapon_Plasma(wx, wy, xd, yd, FUID, WID);
       FFireAngle := FAngle;
-      f := True;
     end;
 
     WEAPON_BFG:
     begin
       g_Weapon_BFGShot(wx, wy, xd, yd, FUID, WID);
       FFireAngle := FAngle;
-      f := True;
     end;
 
-    WEAPON_SUPERPULEMET:
+    WEAPON_SUPERCHAINGUN:
     begin
       g_Sound_PlayExAt('SOUND_WEAPON_FIRESHOTGUN', Gamex, Gamey);
       FFireAngle := FAngle;
-      f := True;
       g_Player_CreateShell(GameX+PLAYER_RECT_CX, GameY+PLAYER_RECT_CX,
                              GameVelX, GameVelY-2, SHELL_SHELL);
     end;
@@ -5674,11 +5744,10 @@ begin
       g_Weapon_flame(wx, wy, xd, yd, FUID, WID);
       FlamerOn;
       FFireAngle := FAngle;
-      f := True;
     end;
   end;
 
-  if not f then Exit;
+  if not visible then Exit;
 
   if (FAngle = 0) or (FAngle = 180) then SetAction(A_ATTACK)
     else if (FAngle = ANGLE_LEFTDOWN) or (FAngle = ANGLE_RIGHTDOWN) then SetAction(A_ATTACKDOWN)
@@ -5771,7 +5840,7 @@ begin
     if not sound_cap_flag[a].IsPlaying() then
       sound_cap_flag[a].Play();
 
-    gTeamStat[FTeam].Goals := gTeamStat[FTeam].Goals + 1;
+    gTeamStat[FTeam].Score += 1;
 
     Result := True;
     if g_Game_IsNet then
@@ -5867,10 +5936,9 @@ end;
 
 function TPlayer.TryDropFlag(): Boolean;
 begin
-  if LongBool(gGameSettings.Options and GAME_OPTION_ALLOWDROPFLAG) then
-    Result := DropFlag(False, LongBool(gGameSettings.Options and GAME_OPTION_THROWFLAG))
-  else
-    Result := False;
+  if (TGameOption.ALLOW_DROP_FLAG in gGameSettings.Options)
+    then Result := DropFlag(False, TGameOption.THROW_FLAG in gGameSettings.Options)
+    else Result := False;
 end;
 
 function TPlayer.DropFlag(Silent: Boolean = True; DoThrow: Boolean = False): Boolean;
@@ -5974,7 +6042,7 @@ begin
   else Result := 0;
 end;
 
-procedure TPlayer.RememberState();
+procedure TPlayer.PreserveState();
 var
   i: Integer;
   SavedState: TPlayerSavedState;
@@ -5992,7 +6060,7 @@ begin
     SavedState.Ammo[i] := FAmmo[i];
   for i := Low(FMaxAmmo) to High(FMaxAmmo) do
     SavedState.MaxAmmo[i] := FMaxAmmo[i];
-  SavedState.Rulez := FRulez - [R_KEY_RED, R_KEY_GREEN, R_KEY_BLUE];
+  SavedState.Inventory := FInventory - [R_KEY_RED, R_KEY_GREEN, R_KEY_BLUE];
 
   FSavedStateNum := -1;
   for i := Low(SavedStates) to High(SavedStates) do
@@ -6011,7 +6079,7 @@ begin
   SavedStates[FSavedStateNum] := SavedState;
 end;
 
-procedure TPlayer.RecallState();
+procedure TPlayer.RestoreState();
 var
   i: Integer;
   SavedState: TPlayerSavedState;
@@ -6036,7 +6104,7 @@ begin
     FAmmo[i] := SavedState.Ammo[i];
   for i := Low(FMaxAmmo) to High(FMaxAmmo) do
     FMaxAmmo[i] := SavedState.MaxAmmo[i];
-  FRulez := SavedState.Rulez;
+  FInventory := SavedState.Inventory;
 
   if gGameSettings.GameType = GT_SERVER then
     MH_SEND_PlayerStats(FUID);
@@ -6120,17 +6188,17 @@ begin
   // Âðåìÿ ïåðåçàðÿäêè îðóæèÿ
   for i := WP_FIRST to WP_LAST do utils.writeInt(st, Word(FReloading[i]));
   // Íàëè÷èå ðþêçàêà
-  utils.writeBool(st, (R_ITEM_BACKPACK in FRulez));
+  utils.writeBool(st, (R_ITEM_BACKPACK in FInventory));
   // Íàëè÷èå êðàñíîãî êëþ÷à
-  utils.writeBool(st, (R_KEY_RED in FRulez));
+  utils.writeBool(st, (R_KEY_RED in FInventory));
   // Íàëè÷èå çåëåíîãî êëþ÷à
-  utils.writeBool(st, (R_KEY_GREEN in FRulez));
+  utils.writeBool(st, (R_KEY_GREEN in FInventory));
   // Íàëè÷èå ñèíåãî êëþ÷à
-  utils.writeBool(st, (R_KEY_BLUE in FRulez));
+  utils.writeBool(st, (R_KEY_BLUE in FInventory));
   // Íàëè÷èå áåðñåðêà
-  utils.writeBool(st, (R_BERSERK in FRulez));
+  utils.writeBool(st, (R_BERSERK in FInventory));
   // Âðåìÿ äåéñòâèÿ ñïåöèàëüíûõ ïðåäìåòîâ
-  for i := MR_SUIT to MR_MAX do utils.writeInt(st, LongWord(FMegaRulez[i]));
+  for i := MR_SUIT to MR_MAX do utils.writeInt(st, LongWord(FPowerups[i]));
   // Âðåìÿ äî ïîâòîðíîãî ðåñïàóíà, ñìåíû îðóæèÿ, èñîëüçîâàíèÿ, çàõâàòà ôëàãà
   for i := T_RESPAWN to T_FLAGCAP do utils.writeInt(st, LongWord(FTime[i]));
   // Íàçâàíèå ìîäåëè
@@ -6224,17 +6292,17 @@ begin
   // Âðåìÿ ïåðåçàðÿäêè îðóæèÿ
   for i := WP_FIRST to WP_LAST do FReloading[i] := utils.readWord(st);
   // Íàëè÷èå ðþêçàêà
-  if utils.readBool(st) then Include(FRulez, R_ITEM_BACKPACK);
+  if utils.readBool(st) then FInventory += [R_ITEM_BACKPACK];
   // Íàëè÷èå êðàñíîãî êëþ÷à
-  if utils.readBool(st) then Include(FRulez, R_KEY_RED);
+  if utils.readBool(st) then FInventory += [R_KEY_RED];
   // Íàëè÷èå çåëåíîãî êëþ÷à
-  if utils.readBool(st) then Include(FRulez, R_KEY_GREEN);
+  if utils.readBool(st) then FInventory += [R_KEY_GREEN];
   // Íàëè÷èå ñèíåãî êëþ÷à
-  if utils.readBool(st) then Include(FRulez, R_KEY_BLUE);
+  if utils.readBool(st) then FInventory += [R_KEY_BLUE];
   // Íàëè÷èå áåðñåðêà
-  if utils.readBool(st) then Include(FRulez, R_BERSERK);
+  if utils.readBool(st) then FInventory += [R_BERSERK];
   // Âðåìÿ äåéñòâèÿ ñïåöèàëüíûõ ïðåäìåòîâ
-  for i := MR_SUIT to MR_MAX do FMegaRulez[i] := utils.readLongWord(st);
+  for i := MR_SUIT to MR_MAX do FPowerups[i] := utils.readLongWord(st);
   // Âðåìÿ äî ïîâòîðíîãî ðåñïàóíà, ñìåíû îðóæèÿ, èñîëüçîâàíèÿ, çàõâàòà ôëàãà
   for i := T_RESPAWN to T_FLAGCAP do FTime[i] := utils.readLongWord(st);
   // Íàçâàíèå ìîäåëè
@@ -6255,14 +6323,13 @@ begin
   end;
   // Îáíîâëÿåì ìîäåëü èãðîêà
   SetModel(str);
-  if gGameSettings.GameMode in [GM_TDM, GM_CTF] then
-    FModel.Color := TEAMCOLOR[FTeam]
-  else
-    FModel.Color := FColor;
+  if gGameSettings.GameMode in [GM_TDM, GM_CTF]
+    then FModel.Color := TEAMCOLOR[FTeam]
+    else FModel.Color := FColor;
 end;
 
 
-procedure TPlayer.AllRulez(Health: Boolean);
+procedure TPlayer.TankRamboCheats(Health: Boolean);
 var
   a: Integer;
 begin
@@ -6275,7 +6342,7 @@ begin
 
   for a := WP_FIRST to WP_LAST do FWeapon[a] := True;
   for a := A_BULLETS to A_HIGH do FAmmo[a] := 30000;
-  FRulez := FRulez+[R_KEY_RED, R_KEY_GREEN, R_KEY_BLUE];
+  FInventory += [R_KEY_RED, R_KEY_GREEN, R_KEY_BLUE];
 end;
 
 procedure TPlayer.RestoreHealthArmor();
@@ -6317,57 +6384,46 @@ procedure TPlayer.GiveItem(ItemType: Byte);
 begin
   case ItemType of
     ITEM_SUIT:
-      if FMegaRulez[MR_SUIT] < gTime+PLAYER_SUIT_TIME then
-      begin
-        FMegaRulez[MR_SUIT] := gTime+PLAYER_SUIT_TIME;
-      end;
+      if FPowerups[MR_SUIT] < gTime+PLAYER_SUIT_TIME then
+        FPowerups[MR_SUIT] := gTime+PLAYER_SUIT_TIME;
 
     ITEM_OXYGEN:
-      if FAir < AIR_MAX then
-      begin
-        FAir := AIR_MAX;
-      end;
+      if FAir < AIR_MAX then FAir := AIR_MAX;
 
     ITEM_MEDKIT_BLACK:
+    begin
+      if not (R_BERSERK in FInventory) then
       begin
-        if not (R_BERSERK in FRulez) then
-        begin
-          Include(FRulez, R_BERSERK);
-          if FBFGFireCounter < 1 then
-          begin
-            FCurrWeap := WEAPON_KASTET;
-            resetWeaponQueue();
-            FModel.SetWeapon(WEAPON_KASTET);
-          end;
-          if gFlash <> 0 then
-            Inc(FPain, 100);
-          FBerserk := gTime+30000;
-        end;
-        if FHealth < PLAYER_HP_SOFT then
+        FInventory += [R_BERSERK];
+        if FBFGFireCounter < 1 then
         begin
-          FHealth := PLAYER_HP_SOFT;
-          FBerserk := gTime+30000;
+          FCurrWeap := WEAPON_IRONFIST;
+          resetWeaponQueue();
+          FModel.SetWeapon(WEAPON_IRONFIST);
         end;
+        if gFlash <> 0 then FPain += 100;
+        FBerserk := gTime+30000;
+      end;
+      if FHealth < PLAYER_HP_SOFT then
+      begin
+        FHealth := PLAYER_HP_SOFT;
+        FBerserk := gTime+30000;
       end;
+    end;
 
     ITEM_INVUL:
-      if FMegaRulez[MR_INVUL] < gTime+PLAYER_INVUL_TIME then
+      if FPowerups[MR_INVUL] < gTime+PLAYER_INVUL_TIME then
       begin
-        FMegaRulez[MR_INVUL] := gTime+PLAYER_INVUL_TIME;
+        FPowerups[MR_INVUL] := gTime+PLAYER_INVUL_TIME;
         FSpawnInvul := 0;
       end;
 
     ITEM_INVIS:
-      if FMegaRulez[MR_INVIS] < gTime+PLAYER_INVIS_TIME then
-      begin
-        FMegaRulez[MR_INVIS] := gTime+PLAYER_INVIS_TIME;
-      end;
+      if FPowerups[MR_INVIS] < gTime+PLAYER_INVIS_TIME then
+        FPowerups[MR_INVIS] := gTime+PLAYER_INVIS_TIME;
 
     ITEM_JETPACK:
-      if FJetFuel < JET_MAX then
-      begin
-        FJetFuel := JET_MAX;
-      end;
+      if FJetFuel < JET_MAX then FJetFuel := JET_MAX;
 
     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);
@@ -6390,7 +6446,7 @@ begin
     ITEM_WEAPON_ROCKETLAUNCHER: FWeapon[WEAPON_ROCKETLAUNCHER] := True;
     ITEM_WEAPON_PLASMA: FWeapon[WEAPON_PLASMA] := True;
     ITEM_WEAPON_BFG: FWeapon[WEAPON_BFG] := True;
-    ITEM_WEAPON_SUPERPULEMET: FWeapon[WEAPON_SUPERPULEMET] := True;
+    ITEM_WEAPON_SUPERCHAINGUN: FWeapon[WEAPON_SUPERCHAINGUN] := True;
     ITEM_WEAPON_FLAMETHROWER: FWeapon[WEAPON_FLAMETHROWER] := True;
 
     ITEM_AMMO_BULLETS: if FAmmo[A_BULLETS] < FMaxAmmo[A_BULLETS] then IncMax(FAmmo[A_BULLETS], 10, FMaxAmmo[A_BULLETS]);
@@ -6421,12 +6477,12 @@ begin
         if FAmmo[A_ROCKETS] < FMaxAmmo[A_ROCKETS] then IncMax(FAmmo[A_ROCKETS], 1, FMaxAmmo[A_ROCKETS]);
         if FAmmo[A_CELLS] < FMaxAmmo[A_CELLS] then IncMax(FAmmo[A_CELLS], 40, FMaxAmmo[A_CELLS]);
 
-        FRulez := FRulez + [R_ITEM_BACKPACK];
+        FInventory += [R_ITEM_BACKPACK];
       end;
 
-    ITEM_KEY_RED: if not (R_KEY_RED in FRulez) then Include(FRulez, R_KEY_RED);
-    ITEM_KEY_GREEN: if not (R_KEY_GREEN in FRulez) then Include(FRulez, R_KEY_GREEN);
-    ITEM_KEY_BLUE: if not (R_KEY_BLUE in FRulez) then Include(FRulez, R_KEY_BLUE);
+    ITEM_KEY_RED: if not (R_KEY_RED in FInventory) then FInventory += [R_KEY_RED];
+    ITEM_KEY_GREEN: if not (R_KEY_GREEN in FInventory) then FInventory += [R_KEY_GREEN];
+    ITEM_KEY_BLUE: if not (R_KEY_BLUE in FInventory) then FInventory += [R_KEY_BLUE];
 
     ITEM_BOTTLE: if FHealth < PLAYER_HP_LIMIT then IncMax(FHealth, 4, PLAYER_HP_LIMIT);
     ITEM_HELMET: if FArmor < PLAYER_AP_LIMIT then IncMax(FArmor, 5, PLAYER_AP_LIMIT);
@@ -6448,12 +6504,8 @@ begin
 
   if BodyInLiquid(0, 0) then
   begin
-    g_GFX_Bubbles(Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2)+Random(3)-1,
-                  Obj.Y+Obj.Rect.Height+8, 1, 8, 4);
-    if Random(2) = 0 then
-      g_Sound_PlayExAt('SOUND_GAME_BUBBLE1', FObj.X, FObj.Y)
-    else
-      g_Sound_PlayExAt('SOUND_GAME_BUBBLE2', FObj.X, FObj.Y);
+    g_Game_Effect_Bubbles(Obj.X+Obj.Rect.X+(Obj.Rect.Width div 2)+Random(3)-1,
+                          Obj.Y+Obj.Rect.Height+8, 1, 8, 4);
     Exit;
   end;
 
@@ -6862,8 +6914,8 @@ var
   end;
 
 begin
-  vsPlayer := LongBool(gGameSettings.Options and GAME_OPTION_BOTVSPLAYER);
-  vsMonster := LongBool(gGameSettings.Options and GAME_OPTION_BOTVSMONSTER);
+  vsPlayer := TGameOption.BOTS_VS_PLAYERS in gGameSettings.Options;
+  vsMonster := TGameOption.BOTS_VS_MONSTERS in gGameSettings.Options;
 
 // Åñëè òåêóùåå îðóæèå íå òî, ÷òî íóæíî, òî ìåíÿåì:
   if FCurrWeap <> FSelectedWeapon then
@@ -6875,8 +6927,8 @@ begin
       RemoveAIFlag('NEEDFIRE');
 
       case FCurrWeap of
-        WEAPON_PLASMA, WEAPON_SUPERPULEMET, WEAPON_CHAINGUN: PressKey(KEY_FIRE, 20);
-        WEAPON_SAW, WEAPON_KASTET, WEAPON_FLAMETHROWER: PressKey(KEY_FIRE, 40);
+        WEAPON_PLASMA, WEAPON_SUPERCHAINGUN, WEAPON_CHAINGUN: PressKey(KEY_FIRE, 20);
+        WEAPON_SAW, WEAPON_IRONFIST, WEAPON_FLAMETHROWER: PressKey(KEY_FIRE, 40);
         else PressKey(KEY_FIRE);
       end;
     end;
@@ -6958,7 +7010,7 @@ begin
            (gPlayers[a].FUID <> FUID) and
            (not SameTeam(FUID, gPlayers[a].FUID)) and
            (not gPlayers[a].NoTarget) and
-           (gPlayers[a].FMegaRulez[MR_INVIS] < gTime) then
+           (gPlayers[a].FPowerups[MR_INVIS] < gTime) then
           begin
             if not TargetOnScreen(gPlayers[a].FObj.X + PLAYER_RECT.X,
                                   gPlayers[a].FObj.Y + PLAYER_RECT.Y) then
@@ -7145,7 +7197,7 @@ begin
             begin // Öåëü - èãðîê
               pla := g_Player_Get(Target.UID);
               if (pla = nil) or (not pla.alive) or pla.NoTarget or
-                 (pla.FMegaRulez[MR_INVIS] >= gTime) then
+                 (pla.FPowerups[MR_INVIS] >= gTime) then
                 Target.UID := 0; // òî çàáûòü öåëü
             end
           else
@@ -7785,7 +7837,7 @@ begin
     Jump(20);
 
 // Âûáèðàåìñÿ èç êèñëîòû, åñëè íåò êîñòþìà, îáîæãëèñü, èëè ìàëî çäîðîâüÿ:
-  if (FMegaRulez[MR_SUIT] < gTime) and ((FLastHit = HIT_ACID) or (Healthy() <= 1)) then
+  if (FPowerups[MR_SUIT] < gTime) and ((FLastHit = HIT_ACID) or (Healthy() <= 1)) then
     if BodyInAcid(0, 0) then
       Jump();
 end;
@@ -7815,7 +7867,7 @@ var
       WEAPON_ROCKETLAUNCHER: Result := FAmmo[A_ROCKETS] >= 1;
       WEAPON_PLASMA: Result := FAmmo[A_CELLS] >= 10;
       WEAPON_BFG: Result := FAmmo[A_CELLS] >= 40;
-      WEAPON_SUPERPULEMET: Result := FAmmo[A_SHELLS] >= 1;
+      WEAPON_SUPERCHAINGUN: Result := FAmmo[A_SHELLS] >= 1;
       WEAPON_FLAMETHROWER: Result := FAmmo[A_FUEL] >= 1;
       else Result := True;
     end;
@@ -7867,7 +7919,7 @@ end;
 
 function TBot.Healthy(): Byte;
 begin
-  if FMegaRulez[MR_INVUL] >= gTime then Result := 3
+  if FPowerups[MR_INVUL] >= gTime then Result := 3
   else if (FHealth > 80) or ((FHealth > 50) and (FArmor > 20)) then Result := 3
   else if (FHealth > 50) then Result := 2
   else if (FHealth > 20) then Result := 1
@@ -7892,7 +7944,7 @@ begin
     begin
       ok := False;
       if (g_GetUIDType(FLastSpawnerUID) = UID_PLAYER) and
-          LongBool(gGameSettings.Options and GAME_OPTION_BOTVSPLAYER) then
+         (TGameOption.BOTS_VS_PLAYERS in gGameSettings.Options) then
         begin // Èãðîê
           pla := g_Player_Get(FLastSpawnerUID);
           ok := not TargetOnScreen(pla.FObj.X + PLAYER_RECT.X,
@@ -7900,7 +7952,7 @@ begin
         end
       else
         if (g_GetUIDType(FLastSpawnerUID) = UID_MONSTER) and
-           LongBool(gGameSettings.Options and GAME_OPTION_BOTVSMONSTER) then
+           (TGameOption.BOTS_VS_MONSTERS in gGameSettings.Options) then
         begin // Ìîíñòð
           mon := g_Monsters_ByUID(FLastSpawnerUID);
           ok := not TargetOnScreen(mon.Obj.X + mon.Obj.Rect.X,
@@ -8018,7 +8070,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.